diff --git a/core/modules/comment/migrations/d7_comment_entity_translation.yml b/core/modules/comment/migrations/d7_comment_entity_translation.yml
new file mode 100644
index 0000000000..01a8060c90
--- /dev/null
+++ b/core/modules/comment/migrations/d7_comment_entity_translation.yml
@@ -0,0 +1,22 @@
+id: d7_comment_entity_translation
+label: Comment entity translations
+migration_tags:
+  - Drupal 7
+  - translation
+  - Content
+source:
+  plugin: d7_comment
+  entity_translation: true
+process:
+  cid: cid
+  subject: subject
+  uid: uid
+  langcode: entity_translation_language
+  content_translation_source: entity_translation_source
+destination:
+  plugin: entity:comment
+  translations: true
+migration_dependencies:
+  required:
+    - d7_comment
+    - d7_entity_translation_settings
diff --git a/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php b/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php
index 4e3f3caa05..220b5a864f 100644
--- a/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php
+++ b/core/modules/comment/src/Plugin/migrate/source/d7/Comment.php
@@ -23,6 +23,14 @@ public function query() {
     $query->innerJoin('node', 'n', 'c.nid = n.nid');
     $query->addField('n', 'type', 'node_type');
     $query->orderBy('c.created');
+
+    if (!empty($this->configuration['entity_translation'])) {
+      $query->innerJoin('entity_translation', 'et', 'et.entity_id = c.cid AND et.entity_type = :entity_type AND source <> :source', [':entity_type' => 'comment', ':source' => '']);
+      $query->addField('et', 'entity_id');
+      $query->addField('et', 'language', 'entity_translation_language');
+      $query->addField('et', 'source', 'entity_translation_source');
+    }
+
     return $query;
   }
 
@@ -36,8 +44,12 @@ public function prepareRow(Row $row) {
     $comment_type = 'comment_node_' . $node_type;
     $row->setSourceProperty('comment_type', 'comment_node_' . $node_type);
 
-    foreach (array_keys($this->getFields('comment', $comment_type)) as $field) {
-      $row->setSourceProperty($field, $this->getFieldValues('comment', $field, $cid));
+    $language = $this->getEntityTranslationLanguage('comment', $cid) ?: $row->getSourceProperty('language');
+    $entity_translatable = $this->isEntityTranslatable('comment', $node_type);
+
+    foreach ($this->getFields('comment', $comment_type) as $field_name => $field) {
+      $translatable = $entity_translatable && $field['translatable'];
+      $row->setSourceProperty($field_name, $this->getFieldValues('comment', $field_name, $cid, NULL, $translatable, $language));
     }
 
     return parent::prepareRow($row);
@@ -75,4 +87,12 @@ public function getIds() {
     return $ids;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function isEntityTranslatable($entity_type, $bundle = NULL) {
+    $entity_translatable = parent::isEntityTranslatable($entity_type, $bundle);
+    return $entity_translatable && (int) $this->variableGet('language_content_type_' . $bundle, 0) === 4;
+  }
+
 }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
index 95275139cc..c340389c0e 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/FieldableEntity.php
@@ -22,13 +22,14 @@
    *   The field instances, keyed by field name.
    */
   protected function getFields($entity_type, $bundle = NULL) {
-    return $this->select('field_config_instance', 'fci')
+    $query = $this->select('field_config_instance', 'fci')
       ->fields('fci')
-      ->condition('entity_type', $entity_type)
-      ->condition('bundle', isset($bundle) ? $bundle : $entity_type)
-      ->condition('deleted', 0)
-      ->execute()
-      ->fetchAllAssoc('field_name');
+      ->fields('fc', ['translatable'])
+      ->condition('fci.entity_type', $entity_type)
+      ->condition('fci.bundle', isset($bundle) ? $bundle : $entity_type)
+      ->condition('fci.deleted', 0);
+    $query->leftJoin('field_config', 'fc', 'fci.field_id = fc.id');
+    return $query->execute()->fetchAllAssoc('field_name');
   }
 
   /**
@@ -36,7 +37,7 @@ protected function getFields($entity_type, $bundle = NULL) {
    *
    * @param string $entity_type
    *   The entity type.
-   * @param string $field
+   * @param string $field_name
    *   The field name.
    * @param int $entity_id
    *   The entity ID.
@@ -48,8 +49,8 @@ protected function getFields($entity_type, $bundle = NULL) {
    *
    * @todo Support multilingual field values.
    */
-  protected function getFieldValues($entity_type, $field, $entity_id, $revision_id = NULL) {
-    $table = (isset($revision_id) ? 'field_revision_' : 'field_data_') . $field;
+  protected function getFieldValues($entity_type, $field_name, $entity_id, $revision_id = NULL, $translatable = FALSE, $language = NULL) {
+    $table = (isset($revision_id) ? 'field_revision_' : 'field_data_') . $field_name;
     $query = $this->select($table, 't')
       ->fields('t')
       ->condition('entity_type', $entity_type)
@@ -58,12 +59,15 @@ protected function getFieldValues($entity_type, $field, $entity_id, $revision_id
     if (isset($revision_id)) {
       $query->condition('revision_id', $revision_id);
     }
+    if ($translatable && $language) {
+      $query->condition('language', $language);
+    }
     $values = [];
     foreach ($query->execute() as $row) {
       foreach ($row as $key => $value) {
         $delta = $row['delta'];
-        if (strpos($key, $field) === 0) {
-          $column = substr($key, strlen($field) + 1);
+        if (strpos($key, $field_name) === 0) {
+          $column = substr($key, strlen($field_name) + 1);
           $values[$delta][$column] = $value;
         }
       }
@@ -71,4 +75,51 @@ protected function getFieldValues($entity_type, $field, $entity_id, $revision_id
     return $values;
   }
 
+  /**
+   * Check if an entity type uses entity translation.
+   *
+   * TODO
+   *
+   * @param string $entity_type
+   *   The entity type.
+   * @param string $bundle
+   *   (optional) The bundle.
+   *
+   * @return bool
+   *   Whether the entity type uses entity translation.
+   */
+  protected function isEntityTranslatable($entity_type, $bundle = NULL) {
+    return in_array($entity_type, $this->variableGet('entity_translation_entity_types', []));
+  }
+
+
+  /**
+   * Get an entity language from the entity translation table.
+   *
+   * @param string $entity_type
+   *   The entity type.
+   * @param int $entity_id
+   *   The entity ID.
+   *
+   * @return string|null
+   *   The entity language or NULL if not language was found.
+   */
+  protected function getEntityTranslationLanguage($entity_type, $entity_id) {
+    if ($this->moduleExists('entity_translation')) {
+      $query = $this->select('entity_translation', 'et')
+        ->fields('et', ['language'])
+        ->condition('entity_type', $entity_type)
+        ->condition('entity_id', $entity_id);
+      if (!empty($this->configuration['entity_translation'])) {
+        $query->condition('source', '', '<>');
+      }
+      else {
+        $query->condition('source', '');
+      }
+      return $query->execute()->fetchField();
+    }
+
+    return NULL;
+  }
+
 }
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index 422849132a..54e36a0545 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -3107,6 +3107,18 @@
   'created' => '1527594929',
   'changed' => '1527594929',
 ))
+->values(array(
+  'entity_type' => 'taxonomy_term',
+  'entity_id' => '4',
+  'revision_id' => '4',
+  'language' => 'en',
+  'source' => '',
+  'uid' => '1',
+  'status' => '1',
+  'translate' => '0',
+  'created' => '1527594929',
+  'changed' => '1527594929',
+))
 ->execute();
 
 $connection->schema()->createTable('entity_translation_revision', array(
diff --git a/core/modules/node/migrations/d7_node_entity_translation.yml b/core/modules/node/migrations/d7_node_entity_translation.yml
new file mode 100644
index 0000000000..fd7a8e082c
--- /dev/null
+++ b/core/modules/node/migrations/d7_node_entity_translation.yml
@@ -0,0 +1,24 @@
+id: d7_node_entity_translation
+label: Node entity translations
+migration_tags:
+  - Drupal 7
+  - translation
+  - Content
+deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
+source:
+  plugin: d7_node
+  entity_translation: true
+process:
+  nid: nid
+  type: type
+  title: title
+  langcode: entity_translation_language
+  content_translation_source: entity_translation_source
+destination:
+  plugin: entity:node
+  translations: true
+  destination_module: content_translation
+migration_dependencies:
+  required:
+    - d7_node
+    - d7_entity_translation_settings
diff --git a/core/modules/node/src/Plugin/migrate/source/d7/Node.php b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
index 1a9037e7a0..1923ff90f5 100644
--- a/core/modules/node/src/Plugin/migrate/source/d7/Node.php
+++ b/core/modules/node/src/Plugin/migrate/source/d7/Node.php
@@ -97,6 +97,13 @@ public function query() {
       $query->condition('n.type', $this->configuration['node_type']);
     }
 
+    if (!empty($this->configuration['entity_translation'])) {
+      $query->innerJoin('entity_translation', 'et', 'et.entity_id = n.nid AND et.entity_type = :entity_type AND source <> :source', [':entity_type' => 'node', ':source' => '']);
+      $query->addField('et', 'entity_id');
+      $query->addField('et', 'language', 'entity_translation_language');
+      $query->addField('et', 'source', 'entity_translation_source');
+    }
+
     return $query;
   }
 
@@ -104,11 +111,16 @@ public function query() {
    * {@inheritdoc}
    */
   public function prepareRow(Row $row) {
+    $nid = $row->getSourceProperty('nid');
+    $vid = $row->getSourceProperty('vid');
+    $type = $row->getSourceProperty('type');
+    $language = $this->getEntityTranslationLanguage('node', $nid) ?: $row->getSourceProperty('language');
+    $entity_translatable = $this->isEntityTranslatable('node', $type);
+
     // Get Field API field values.
-    foreach (array_keys($this->getFields('node', $row->getSourceProperty('type'))) as $field) {
-      $nid = $row->getSourceProperty('nid');
-      $vid = $row->getSourceProperty('vid');
-      $row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid, $vid));
+    foreach ($this->getFields('node', $type) as $field_name => $field) {
+      $translatable = $entity_translatable && $field['translatable'];
+      $row->setSourceProperty($field_name, $this->getFieldValues('node', $field_name, $nid, $vid, $translatable, $language));
     }
 
     // Make sure we always have a translation set.
@@ -168,4 +180,12 @@ protected function handleTranslations(SelectInterface $query) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function isEntityTranslatable($entity_type, $bundle = NULL) {
+    $entity_translatable = parent::isEntityTranslatable($entity_type, $bundle);
+    return $entity_translatable && (int) $this->variableGet('language_content_type_' . $bundle, 0) === 4;
+  }
+
 }
diff --git a/core/modules/taxonomy/migrations/d7_taxonomy_term_entity_translation.yml b/core/modules/taxonomy/migrations/d7_taxonomy_term_entity_translation.yml
new file mode 100644
index 0000000000..391ab92b82
--- /dev/null
+++ b/core/modules/taxonomy/migrations/d7_taxonomy_term_entity_translation.yml
@@ -0,0 +1,22 @@
+id: d7_taxonomy_term_entity_translation
+label: Taxonomy term entity translations
+migration_tags:
+  - Drupal 7
+  - translation
+  - Content
+deriver: Drupal\taxonomy\Plugin\migrate\D7TaxonomyTermDeriver
+source:
+  plugin: d7_taxonomy_term
+  entity_translation: true
+process:
+  tid: tid
+  name: name
+  langcode: entity_translation_language
+  content_translation_source: entity_translation_source
+destination:
+  plugin: entity:taxonomy_term
+  translations: true
+migration_dependencies:
+  required:
+    - d7_taxonomy_term
+    - d7_entity_translation_settings
diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php
index 93b0fc4aaa..be4bf07fe6 100644
--- a/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php
+++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/Term.php
@@ -32,6 +32,13 @@ public function query() {
       $query->condition('tv.machine_name', (array) $this->configuration['bundle'], 'IN');
     }
 
+    if (!empty($this->configuration['entity_translation'])) {
+      $query->innerJoin('entity_translation', 'et', 'et.entity_id = td.tid AND et.entity_type = :entity_type AND source <> :source', [':entity_type' => 'taxonomy_term', ':source' => '']);
+      $query->addField('et', 'entity_id');
+      $query->addField('et', 'language', 'entity_translation_language');
+      $query->addField('et', 'source', 'entity_translation_source');
+    }
+
     return $query;
   }
 
@@ -56,10 +63,17 @@ public function fields() {
    * {@inheritdoc}
    */
   public function prepareRow(Row $row) {
+    $tid = $row->getSourceProperty('tid');
+    $vocabulary = $row->getSourceProperty('machine_name');
+    $default_language = $this->variableGet('language_default', FALSE);
+    $default_language = $default_language ? $default_language->language : 'en';
+    $language = $this->getEntityTranslationLanguage('taxonomy_term', $tid) ?: $default_language;
+    $entity_translatable = $this->isEntityTranslatable('taxonomy_term', $vocabulary);
+
     // Get Field API field values.
-    foreach (array_keys($this->getFields('taxonomy_term', $row->getSourceProperty('machine_name'))) as $field) {
-      $tid = $row->getSourceProperty('tid');
-      $row->setSourceProperty($field, $this->getFieldValues('taxonomy_term', $field, $tid));
+    foreach ($this->getFields('taxonomy_term', $vocabulary) as $field_name => $field) {
+      $translatable = $entity_translatable && $field['translatable'];
+      $row->setSourceProperty($field_name, $this->getFieldValues('taxonomy_term', $field_name, $tid, NULL, $translatable, $language));
     }
 
     // Find parents for this row.
@@ -86,4 +100,12 @@ public function getIds() {
     return $ids;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function isEntityTranslatable($entity_type, $bundle = NULL) {
+    $entity_translatable = parent::isEntityTranslatable($entity_type, $bundle);
+    return $entity_translatable && in_array($bundle, $this->variableGet('entity_translation_taxonomy', []));
+  }
+
 }
diff --git a/core/modules/user/migrations/d7_user.yml b/core/modules/user/migrations/d7_user.yml
index 00eabf2c7f..35061dbb7f 100644
--- a/core/modules/user/migrations/d7_user.yml
+++ b/core/modules/user/migrations/d7_user.yml
@@ -21,7 +21,7 @@ process:
   timezone: timezone
   langcode:
     plugin: user_langcode
-    source: language
+    source: user_language
     fallback_to_site_default: false
   preferred_langcode:
     plugin: user_langcode
diff --git a/core/modules/user/migrations/d7_user_entity_translation.yml b/core/modules/user/migrations/d7_user_entity_translation.yml
new file mode 100644
index 0000000000..f201de5120
--- /dev/null
+++ b/core/modules/user/migrations/d7_user_entity_translation.yml
@@ -0,0 +1,23 @@
+id: d7_user_entity_translation
+label: User entity translations
+migration_tags:
+  - Drupal 7
+  - translation
+  - Content
+class: Drupal\user\Plugin\migrate\User
+source:
+  plugin: d7_user
+  entity_translation: true
+process:
+  uid: uid
+  name: name
+  mail: mail
+  langcode: entity_translation_language
+  content_translation_source: entity_translation_source
+destination:
+  plugin: entity:user
+  translations: true
+migration_dependencies:
+  required:
+    - d7_user
+    - d7_entity_translation_settings
diff --git a/core/modules/user/src/Plugin/migrate/source/d7/User.php b/core/modules/user/src/Plugin/migrate/source/d7/User.php
index 41f9ab4d6e..ae4808e20d 100644
--- a/core/modules/user/src/Plugin/migrate/source/d7/User.php
+++ b/core/modules/user/src/Plugin/migrate/source/d7/User.php
@@ -19,9 +19,18 @@ class User extends FieldableEntity {
    * {@inheritdoc}
    */
   public function query() {
-    return $this->select('users', 'u')
+    $query = $this->select('users', 'u')
       ->fields('u')
       ->condition('u.uid', 0, '>');
+
+    if (!empty($this->configuration['entity_translation'])) {
+      $query->innerJoin('entity_translation', 'et', 'et.entity_id = u.uid AND et.entity_type = :entity_type AND source <> :source', [':entity_type' => 'user', ':source' => '']);
+      $query->addField('et', 'entity_id');
+      $query->addField('et', 'language', 'entity_translation_language');
+      $query->addField('et', 'source', 'entity_translation_source');
+    }
+
+    return $query;
   }
 
   /**
@@ -71,9 +80,17 @@ public function prepareRow(Row $row) {
 
     $row->setSourceProperty('data', unserialize($row->getSourceProperty('data')));
 
+    $uid = $row->getSourceProperty('uid');
+    $default_language = $this->variableGet('language_default', FALSE);
+    $default_language = $default_language ? $default_language->language : 'en';
+    $language = $this->getEntityTranslationLanguage('user', $uid) ?: $default_language;
+    $entity_translatable = $this->isEntityTranslatable('user');
+    $row->setSourceProperty('user_language', $language);
+
     // Get Field API field values.
-    foreach (array_keys($this->getFields('user')) as $field) {
-      $row->setSourceProperty($field, $this->getFieldValues('user', $field, $row->getSourceProperty('uid')));
+    foreach ($this->getFields('user') as $field_name => $field) {
+      $translatable = $entity_translatable && $field['translatable'];
+      $row->setSourceProperty($field_name, $this->getFieldValues('user', $field_name, $uid, NULL, $translatable, $language));
     }
 
     // Get profile field values. This code is lifted directly from the D6
