diff --git a/revisioning.info b/revisioning.info
index 74718ae..7d23dcb 100644
--- a/revisioning.info
+++ b/revisioning.info
@@ -14,3 +14,5 @@ files[] = views/revisioning_handler_filter_node_state.inc
 files[] = views/revisioning_handler_filter_revision_state.inc
 files[] = views/revisioning_handler_filter_revision_latest.inc
 files[] = views/revisioning_handler_filter_revision_latest_published.inc
+files[] = revisioning.translation_handler.inc
+files[] = revisioning.test
diff --git a/revisioning.module b/revisioning.module
index 712cbb0..6f45c5b 100644
--- a/revisioning.module
+++ b/revisioning.module
@@ -441,6 +441,24 @@ function revisioning_node_load($nodes, $types) {
 }
 
 /**
+ * Implements hook_entity_info_alter().
+ */
+function revisioning_entity_info_alter(&$entity_info) {
+  // If the Entity Translation module exists, register our own path scheme. This
+  // will allow the default revision form to contain the correct translation
+  // data. Override the default class with our own, so the class can tell the
+  // system to use the correct path scheme.
+  if (module_exists('entity_translation')) {
+    $et_info = &$entity_info['node']['translation']['entity_translation'];
+    $et_info['class'] = 'EntityTranslationNodeRevisioningHandler';
+    $et_info['path schemes']['revisioning'] = array(
+      'view path' => 'node/%node/revisions/%vid/view',
+      'edit path' => 'node/%node/revisions/%vid/edit',
+    );
+  }
+}
+
+/**
  * Implements hook_entity_prepare_view().
  *
  * First of the dont_display hooks.
diff --git a/revisioning.pages.inc b/revisioning.pages.inc
index cc92630..6cfdb53 100644
--- a/revisioning.pages.inc
+++ b/revisioning.pages.inc
@@ -19,8 +19,20 @@ function revisioning_form_alter(&$form, &$form_state, $form_id) {
 
     $is_moderated_content = isset($node->revision_moderation) ? $node->revision_moderation : revisioning_content_is_moderated($form['type']['#value'], $node);
 
+    // Make sure we are not adding a new translation, in which case we do not
+    // create a new revision.
+    $et_add_translation = FALSE;
+    if (module_exists('entity_translatsion') && !empty($node->nid) && entity_translation_enabled('node', $node)) {
+      $et_add_translation = !!preg_match('@edit/add/.+?/.+?$@', $form['#action']);
+
+      // Disable revision if adding a new translation.
+      if ($et_add_translation && !empty($node->is_current)) {
+        $node->revision = FALSE;
+      }
+    }
+
     // Alter the Create/Edit content form, if subject to moderation.
-    if ($is_moderated_content) {
+    if ($is_moderated_content && !$et_add_translation) {
       // "Create new revision" must be set when the node is to be moderated.
       $node->revision = TRUE;
       // Next line is not essential, just ensures form options are
@@ -60,7 +72,9 @@ function revisioning_form_alter(&$form, &$form_state, $form_id) {
         '#type' => 'radios',
         '#options' => $options,
         '#default_value' => isset($node->nid)
-          ? (int) $node->revision + (int) $is_moderated_content
+          ? (int) $node->revision + (int) $is_moderated_content - (
+            $et_add_translation ? (int) $node->is_current : 0
+          )
           : ($is_moderated_content ? REVISIONING_NEW_REVISION_WITH_MODERATION : REVISIONING_NEW_REVISION_NO_MODERATION),
       );
       unset($form['revision_information']['revision']);
diff --git a/revisioning.test b/revisioning.test
new file mode 100644
index 0000000..f0acdc4
--- /dev/null
+++ b/revisioning.test
@@ -0,0 +1,117 @@
+<?php
+
+class RevisioningETTestCase extends DrupalWebTestCase {
+
+  protected $profile = 'minimal';
+
+  public static function getInfo() {
+    return array(
+      'name' => "Revisioning Entity translation integration",
+      'description' => "Test the revisioning logic integration with the Entity translation module.",
+      'group' => "Revisioning",
+    );
+  }
+
+  public function setUp() {
+    parent::setUp('revisioning');
+    if (module_enable(array('entity_translation'), TRUE)) {
+      // Enable another language.
+      $info = language_negotiation_info();
+      locale_add_language('fr');
+      language_negotiation_set('language_content', array(
+        'locale-url' => $info['locale-url'],
+        'language-default' => $info['language-default'],
+      ));
+
+      // Create a content type with a translatable field. Make sure we enable
+      // translations for it.
+      node_type_save((object) array(
+        'type' => 'test_ct',
+        'name' => 'Test content type',
+        'base' => 'node_content',
+      ));
+      field_create_field(array(
+        'field_name' => 'test_field',
+        'cardinality' => 1,
+        'type' => 'text',
+        'translatable' => 1,
+      ));
+      field_create_instance(array(
+        'entity_type' => 'node',
+        'bundle' => 'test_ct',
+        'field_name' => 'test_field',
+        'label' => 'Test field',
+      ));
+      module_load_include('inc', 'entity_translation', 'entity_translation.node');
+      variable_set('language_content_type_test_ct', ENTITY_TRANSLATION_ENABLED);
+      variable_set('entity_translation_settings_node__test_ct', array(
+        'default_language' => 'en',
+        'hide_language_selector' => 0,
+        'exclude_language_none' => 1,
+        'lock_language' => 0,
+        'shared_fields_original_only' => 1,
+      ));
+
+      // Activate revisioning.
+      variable_set('node_options_test_ct', array('revision_moderation', 'revision'));
+
+      // Clear all caches.
+      $this->resetAll();
+
+      // Create a new admin user and log in.
+      $admin = $this->drupalCreateUser(array_keys(module_invoke_all('permission')));
+      $this->drupalLogin($admin);
+    }
+    else {
+      $this->fail('This test requires the Entity Translation module to run.');
+    }
+  }
+
+  public function testET() {
+    // Create a node.
+    $node = $this->drupalCreateNode(array(
+      'type' => 'test_ct',
+      'language' => 'en',
+      'test_field' => array(
+        'en' => array(
+          array('value' => $this->randomName(20) . '--en'),
+        ),
+      ),
+      // This is to prevent a Fatal Error. It is fixed in the latest dev release
+      // of Drupal 7 (not yet published in Drupal 7.44).
+      'body' => array(
+        LANGUAGE_NONE => array(array()),
+        'en' => array(array()),
+      ),
+    ));
+
+    // Publish the current revision, and create a new one, pending.
+    _revisioning_publish_latest_revision($node);
+    $published_vid = $node->vid;
+    $node->title = $this->randomName(8);
+    node_save($node);
+    $this->assertEqual(2, revisioning_get_number_of_revisions($node->nid));
+
+    // Go to the translation tab. Should show an "add" link. Add a new
+    // translation.
+    $this->drupalGet("node/{$node->nid}/translate");
+    $this->assertLink('add');
+    $this->clickLink('add');
+    $edit = array(
+      'test_field[fr][0][value]' => $this->randomName(8) . '--fr',
+    );
+    $this->drupalPost(NULL, $edit, 'Save');
+    $this->drupalGet("fr/node/{$node->nid}/revisions/{$node->vid}/view");
+    $this->assertText('--fr');
+    $this->drupalGet("node/{$node->nid}/revisions/{$node->vid}/view");
+    $this->assertText('--en');
+
+    // Should have registered the translation, and there should be no more "add"
+    // link. It should not have created a new revision either, and should not
+    // have published the currently pending revision.
+    $this->drupalGet("node/{$node->nid}/translate");
+    $this->assertNoLink('add');
+    $this->assertEqual(2, revisioning_get_number_of_revisions($node->nid));
+    $this->assertEqual($published_vid, revisioning_get_current_node_revision_id($node->nid));
+  }
+}
diff --git a/revisioning.translation_handler.inc b/revisioning.translation_handler.inc
new file mode 100644
index 0000000..862935d
--- /dev/null
+++ b/revisioning.translation_handler.inc
@@ -0,0 +1,89 @@
+<?php
+
+class EntityTranslationNodeRevisioningHandler extends EntityTranslationNodeHandler {
+
+  protected $isModerated = FALSE;
+  const REVISIONING_SCHEME = 'revisioning';
+
+  public function __construct($entity_type, $entity_info, $entity) {
+    parent::__construct('node', $entity_info, $entity);
+    if ($this->isModerated = revisioning_content_is_moderated($this->bundle, $entity)) {
+      $this->refreshEntity();
+      $this->setPathScheme(self::REVISIONING_SCHEME);
+    }
+  }
+
+  public function initPathScheme($path = NULL) {
+    if ($this->isModerated) {
+      $this->setPathScheme(self::REVISIONING_SCHEME);
+      return self::REVISIONING_SCHEME;
+    }
+    else {
+      return parent::initPathScheme($path);
+    }
+  }
+
+  public function getTranslations() {
+    $this->refreshEntity();
+    return parent::getTranslations();
+  }
+
+  protected function getPathInstance($path) {
+    if (!empty($this->pathScheme) && $this->pathScheme == self::REVISIONING_SCHEME) {
+      $path_segments = explode('/', $path);
+      foreach ($path_segments as $index => $segment) {
+        if ($segment == '%node') {
+          $path_segments[$index] = $this->getEntityId();
+        }
+        elseif ($segment == '%vid') {
+          $path_segments[$index] = $this->revisionId;
+        }
+        elseif ($segment{0} == '%' && isset($this->routerMap[$index])) {
+          $path_segments[$index] = $this->routerMap[$index];
+        }
+      }
+
+      return implode('/', $path_segments);
+    }
+    else {
+      return parent::getPathInstance($path);
+    }
+  }
+
+  public function setEntity($entity) {
+    // Sometimes this method is called right after the constructor, effectively
+    // resetting our node to an older revision. Allow it to be stored again, but
+    // call our refresh method right after it, to be sure we have the right
+    // data.
+    parent::setEntity($entity);
+    $this->refreshEntity();
+  }
+
+  protected function refreshEntity() {
+    // @todo Always load latest revision?? At least we are sure it contains
+    // translation data; for the last published revision, we cannot be sure...
+    $latest_revision_id = revisioning_get_latest_revision_id($this->getEntityId());
+    if ($latest_revision_id !== $this->revisionId) {
+      $old_revision_id = $this->revisionId;
+      parent::setEntity(node_load($this->getEntityId(), $latest_revision_id));
+
+      // If we needed to refresh, it is possible we have a sibling floating
+      // around which contains the actual entity form. This can happen in our
+      // case, as the correct revision is not always loaded in each context (for
+      // example, a different node could be loaded for the access callback,
+      // meaning the entity_translation_get_handler() function will return a new
+      // handler, different from our current one. In that case, check if the
+      // factory contains another instance for the same node, but for the
+      // latest revision ID. If so, check if we are in an entity form context.
+      // This is necessary to get the language tabs right.
+      if (!empty($this->factory)) {
+        $handler = $this->factory->getHandler('node', $this->entity);
+        if ($handler != $this) {
+          if ($handler->isEntityForm()) {
+            $this->entityForm = TRUE;
+          }
+        }
+      }
+    }
+  }
+}
