diff --git a/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml b/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d0b238567e84752befeac81907b607c521ad03b1
--- /dev/null
+++ b/core/modules/content_translation/migrations/d7_taxonomy_term_localized_translation.yml
@@ -0,0 +1,45 @@
+id: d7_taxonomy_term_localized_translation
+label: Taxonomy localized term translations
+migration_tags:
+  - Drupal 7
+  - Content
+  - Multilingual
+source:
+  plugin: d7_term_localized_translation
+  translations: true
+process:
+  # If you are using this file to build a custom migration consider removing
+  # the tid field to allow incremental migrations.
+  tid: tid
+  # Use the language from the locales_target table.
+  langcode: ltlanguage
+  vid:
+    plugin: migration
+    migration: d7_taxonomy_vocabulary
+    source: vid
+  name:
+    -
+      plugin: callback
+      source:
+        - name_translated
+        - name
+      callable: array_filter
+    -
+      plugin: callback
+      callable: current
+  description:
+    -
+      plugin: callback
+      source:
+        - description_translated
+        - description
+      callable: array_filter
+    -
+      plugin: callback
+      callable: current
+destination:
+  plugin: entity:taxonomy_term
+  translations: true
+migration_dependencies:
+  required:
+    - d7_taxonomy_term
diff --git a/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml b/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
index f560df5be76355eecbc275fc5674bb6a70e8babe..13705b949c439c8a88413538a374b740d7f97ede 100644
--- a/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
+++ b/core/modules/content_translation/migrations/state/content_translation.migrate_drupal.yml
@@ -35,5 +35,6 @@ not_finished:
     i18n: content_translation
     # menu links.
     i18n_menu: content_translation
-    # localized.
+    # Migrate taxonomy term references
+    # https://www.drupal.org/project/drupal/issues/3035392
     i18n_taxonomy: content_translation
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index dcdb0897d31d3863acf9d00fd9e17219d19e7d64..87f234fc261e2f92477845c6347dac48549ae738 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -4201,7 +4201,7 @@
   'storage_module' => 'field_sql_storage',
   'storage_active' => '1',
   'locked' => '0',
-  'data' => 'a:7:{s:12:"translatable";i:0;s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:14:"vocablocalized";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:29:"title_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:31:"field_data_field_vocab_localize";a:1:{s:3:"tid";s:24:"field_vocab_localize_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:35:"field_revision_field_vocab_localize";a:1:{s:3:"tid";s:24:"field_vocab_localize_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"44";}',
+  'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:14:"vocablocalized";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:28:"i18n_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:31:"field_data_field_vocab_localize";a:1:{s:3:"tid";s:24:"field_vocab_localize_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:35:"field_revision_field_vocab_localize";a:1:{s:3:"tid";s:24:"field_vocab_localize_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"44";}',
   'cardinality' => '1',
   'translatable' => '0',
   'deleted' => '0',
@@ -4216,7 +4216,7 @@
   'storage_module' => 'field_sql_storage',
   'storage_active' => '1',
   'locked' => '0',
-  'data' => 'a:7:{s:12:"translatable";i:0;s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:14:"vocabtranslate";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:29:"title_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:32:"field_data_field_vocab_translate";a:1:{s:3:"tid";s:25:"field_vocab_translate_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:36:"field_revision_field_vocab_translate";a:1:{s:3:"tid";s:25:"field_vocab_translate_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"45";}',
+  'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:14:"vocabtranslate";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:28:"i18n_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:32:"field_data_field_vocab_translate";a:1:{s:3:"tid";s:25:"field_vocab_translate_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:36:"field_revision_field_vocab_translate";a:1:{s:3:"tid";s:25:"field_vocab_translate_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"45";}',
   'cardinality' => '1',
   'translatable' => '0',
   'deleted' => '0',
@@ -4231,7 +4231,7 @@
   'storage_module' => 'field_sql_storage',
   'storage_active' => '1',
   'locked' => '0',
-  'data' => 'a:7:{s:12:"translatable";i:0;s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:10:"vocabfixed";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:29:"title_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:28:"field_data_field_vocab_fixed";a:1:{s:3:"tid";s:21:"field_vocab_fixed_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:32:"field_revision_field_vocab_fixed";a:1:{s:3:"tid";s:21:"field_vocab_fixed_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"46";}',
+  'data' => 'a:7:{s:12:"translatable";s:1:"0";s:12:"entity_types";a:0:{}s:8:"settings";a:3:{s:14:"allowed_values";a:1:{i:0;a:2:{s:10:"vocabulary";s:10:"vocabfixed";s:6:"parent";s:1:"0";}}s:21:"options_list_callback";s:28:"i18n_taxonomy_allowed_values";s:23:"entity_translation_sync";b:0;}s:7:"storage";a:5:{s:4:"type";s:17:"field_sql_storage";s:8:"settings";a:0:{}s:6:"module";s:17:"field_sql_storage";s:6:"active";s:1:"1";s:7:"details";a:1:{s:3:"sql";a:2:{s:18:"FIELD_LOAD_CURRENT";a:1:{s:28:"field_data_field_vocab_fixed";a:1:{s:3:"tid";s:21:"field_vocab_fixed_tid";}}s:19:"FIELD_LOAD_REVISION";a:1:{s:32:"field_revision_field_vocab_fixed";a:1:{s:3:"tid";s:21:"field_vocab_fixed_tid";}}}}}s:12:"foreign keys";a:1:{s:3:"tid";a:2:{s:5:"table";s:18:"taxonomy_term_data";s:7:"columns";a:1:{s:3:"tid";s:3:"tid";}}}s:7:"indexes";a:1:{s:3:"tid";a:1:{i:0;s:3:"tid";}}s:2:"id";s:2:"46";}',
   'cardinality' => '1',
   'translatable' => '0',
   'deleted' => '0',
@@ -16199,183 +16199,183 @@
 ))
 ->values(array(
   'lid' => '77',
-  'textgroup' => 'field',
-  'context' => 'comment_body:comment_node_article:label',
-  'objectid' => 'comment_node_article',
-  'type' => 'comment_body',
-  'property' => 'label',
-  'objectindex' => '0',
+  'textgroup' => 'taxonomy',
+  'context' => 'term:20:name',
+  'objectid' => '20',
+  'type' => 'term',
+  'property' => 'name',
+  'objectindex' => '20',
   'format' => '',
 ))
 ->values(array(
   'lid' => '78',
-  'textgroup' => 'field',
-  'context' => 'comment_body:comment_node_blog:label',
-  'objectid' => 'comment_node_blog',
-  'type' => 'comment_body',
-  'property' => 'label',
-  'objectindex' => '0',
-  'format' => '',
+  'textgroup' => 'taxonomy',
+  'context' => 'term:20:description',
+  'objectid' => '20',
+  'type' => 'term',
+  'property' => 'description',
+  'objectindex' => '20',
+  'format' => 'filtered_html',
 ))
 ->values(array(
   'lid' => '79',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:1:name',
-  'objectid' => '1',
-  'type' => 'vocabulary',
+  'context' => 'term:19:name',
+  'objectid' => '19',
+  'type' => 'term',
   'property' => 'name',
-  'objectindex' => '1',
+  'objectindex' => '19',
   'format' => '',
 ))
 ->values(array(
   'lid' => '80',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:1:description',
-  'objectid' => '1',
-  'type' => 'vocabulary',
+  'context' => 'term:19:description',
+  'objectid' => '19',
+  'type' => 'term',
   'property' => 'description',
-  'objectindex' => '1',
-  'format' => '',
+  'objectindex' => '19',
+  'format' => 'filtered_html',
 ))
 ->values(array(
   'lid' => '81',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:3:name',
-  'objectid' => '3',
+  'context' => 'vocabulary:2:name',
+  'objectid' => '2',
   'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '3',
+  'objectindex' => '2',
   'format' => '',
 ))
 ->values(array(
   'lid' => '82',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:3:description',
-  'objectid' => '3',
+  'context' => 'vocabulary:2:description',
+  'objectid' => '2',
   'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '3',
+  'objectindex' => '2',
   'format' => '',
 ))
 ->values(array(
   'lid' => '83',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:4:name',
-  'objectid' => '4',
+  'context' => 'vocabulary:1:name',
+  'objectid' => '1',
   'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '4',
+  'objectindex' => '1',
   'format' => '',
 ))
 ->values(array(
   'lid' => '84',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:4:description',
-  'objectid' => '4',
+  'context' => 'vocabulary:1:description',
+  'objectid' => '1',
   'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '4',
+  'objectindex' => '1',
   'format' => '',
 ))
 ->values(array(
   'lid' => '85',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:5:name',
-  'objectid' => '5',
+  'context' => 'vocabulary:3:name',
+  'objectid' => '3',
   'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '5',
+  'objectindex' => '3',
   'format' => '',
 ))
 ->values(array(
   'lid' => '86',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:5:description',
-  'objectid' => '5',
+  'context' => 'vocabulary:3:description',
+  'objectid' => '3',
   'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '5',
+  'objectindex' => '3',
   'format' => '',
 ))
 ->values(array(
   'lid' => '87',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:6:name',
-  'objectid' => '6',
+  'context' => 'vocabulary:7:name',
+  'objectid' => '7',
   'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '6',
+  'objectindex' => '7',
   'format' => '',
 ))
 ->values(array(
   'lid' => '88',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:6:description',
-  'objectid' => '6',
+  'context' => 'vocabulary:7:description',
+  'objectid' => '7',
   'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '6',
+  'objectindex' => '7',
   'format' => '',
 ))
 ->values(array(
   'lid' => '89',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:7:name',
-  'objectid' => '7',
+  'context' => 'vocabulary:5:name',
+  'objectid' => '5',
   'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '7',
+  'objectindex' => '5',
   'format' => '',
 ))
 ->values(array(
   'lid' => '90',
   'textgroup' => 'taxonomy',
-  'context' => 'vocabulary:7:description',
-  'objectid' => '7',
+  'context' => 'vocabulary:5:description',
+  'objectid' => '5',
   'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '7',
+  'objectindex' => '5',
   'format' => '',
 ))
 ->values(array(
   'lid' => '91',
   'textgroup' => 'taxonomy',
-  'context' => 'term:19:name',
-  'objectid' => '19',
-  'type' => 'term',
+  'context' => 'vocabulary:6:name',
+  'objectid' => '6',
+  'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '19',
+  'objectindex' => '6',
   'format' => '',
 ))
 ->values(array(
   'lid' => '92',
   'textgroup' => 'taxonomy',
-  'context' => 'term:19:description',
-  'objectid' => '19',
-  'type' => 'term',
+  'context' => 'vocabulary:6:description',
+  'objectid' => '6',
+  'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '19',
-  'format' => 'filtered_html',
+  'objectindex' => '6',
+  'format' => '',
 ))
 ->values(array(
   'lid' => '93',
   'textgroup' => 'taxonomy',
-  'context' => 'term:20:name',
-  'objectid' => '20',
-  'type' => 'term',
+  'context' => 'vocabulary:4:name',
+  'objectid' => '4',
+  'type' => 'vocabulary',
   'property' => 'name',
-  'objectindex' => '20',
+  'objectindex' => '4',
   'format' => '',
 ))
 ->values(array(
   'lid' => '94',
   'textgroup' => 'taxonomy',
-  'context' => 'term:20:description',
-  'objectid' => '20',
-  'type' => 'term',
+  'context' => 'vocabulary:4:description',
+  'objectid' => '4',
+  'type' => 'vocabulary',
   'property' => 'description',
-  'objectindex' => '20',
-  'format' => 'filtered_html',
+  'objectindex' => '4',
+  'format' => '',
 ))
 ->values(array(
   'lid' => '95',
@@ -17397,6 +17397,26 @@
   'objectindex' => '0',
   'format' => '',
 ))
+->values(array(
+  'lid' => '795',
+  'textgroup' => 'field',
+  'context' => 'comment_body:comment_node_article:label',
+  'objectid' => 'comment_node_article',
+  'type' => 'comment_body',
+  'property' => 'label',
+  'objectindex' => '0',
+  'format' => '',
+))
+->values(array(
+  'lid' => '796',
+  'textgroup' => 'field',
+  'context' => 'comment_body:comment_node_blog:label',
+  'objectid' => 'comment_node_blog',
+  'type' => 'comment_body',
+  'property' => 'label',
+  'objectindex' => '0',
+  'format' => '',
+))
 ->execute();
 $connection->schema()->createTable('i18n_translation_set', array(
   'fields' => array(
@@ -18421,6 +18441,150 @@
   'context' => 'user:login:title',
   'version' => '1',
 ))
+->values(array(
+  'lid' => '77',
+  'location' => 'taxonomy:term:20:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'DS9',
+  'context' => 'term:20:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '78',
+  'location' => 'taxonomy:term:20:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Terok Nor',
+  'context' => 'term:20:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '79',
+  'location' => 'taxonomy:term:19:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'Jupiter Station',
+  'context' => 'term:19:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '80',
+  'location' => 'taxonomy:term:19:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Holographic research.',
+  'context' => 'term:19:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '81',
+  'location' => 'taxonomy:vocabulary:2:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'Sujet de discussion',
+  'context' => 'vocabulary:2:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '82',
+  'location' => 'taxonomy:vocabulary:2:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Forum navigation vocabulary',
+  'context' => 'vocabulary:2:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '83',
+  'location' => 'taxonomy:vocabulary:1:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'Tags',
+  'context' => 'vocabulary:1:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '84',
+  'location' => 'taxonomy:vocabulary:1:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Use tags to group articles on similar topics into categories.',
+  'context' => 'vocabulary:1:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '85',
+  'location' => 'taxonomy:vocabulary:3:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'Test Vocabulary',
+  'context' => 'vocabulary:3:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '86',
+  'location' => 'taxonomy:vocabulary:3:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'This is the vocabulary description',
+  'context' => 'vocabulary:3:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '87',
+  'location' => 'taxonomy:vocabulary:7:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'VocabFixed',
+  'context' => 'vocabulary:7:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '88',
+  'location' => 'taxonomy:vocabulary:7:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Vocabulary fixed option',
+  'context' => 'vocabulary:7:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '89',
+  'location' => 'taxonomy:vocabulary:5:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'VocabLocalized',
+  'context' => 'vocabulary:5:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '90',
+  'location' => 'taxonomy:vocabulary:5:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Vocabulary localize option',
+  'context' => 'vocabulary:5:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '91',
+  'location' => 'taxonomy:vocabulary:6:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'VocabTranslate',
+  'context' => 'vocabulary:6:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '92',
+  'location' => 'taxonomy:vocabulary:6:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'Vocabulary translate option',
+  'context' => 'vocabulary:6:description',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '93',
+  'location' => 'taxonomy:vocabulary:4:name',
+  'textgroup' => 'taxonomy',
+  'source' => 'vocabulary name clearly different than machine name and much longer than thirty two characters',
+  'context' => 'vocabulary:4:name',
+  'version' => '1',
+))
+->values(array(
+  'lid' => '94',
+  'location' => 'taxonomy:vocabulary:4:description',
+  'textgroup' => 'taxonomy',
+  'source' => 'description of vocabulary name much longer than thirty two characters',
+  'context' => 'vocabulary:4:description',
+  'version' => '1',
+))
 ->execute();
 $connection->schema()->createTable('locales_target', array(
   'fields' => array(
@@ -18501,6 +18665,22 @@
   'plural' => '0',
   'i18n_status' => '0',
 ))
+->values(array(
+  'lid' => '77',
+  'translation' => 'fr - DS9 (localized)',
+  'language' => 'fr',
+  'plid' => '0',
+  'plural' => '0',
+  'i18n_status' => '0',
+))
+->values(array(
+  'lid' => '78',
+  'translation' => 'fr - Terok Nor (localized)',
+  'language' => 'fr',
+  'plid' => '0',
+  'plural' => '0',
+  'i18n_status' => '0',
+))
 ->values(array(
   'lid' => '85',
   'translation' => 'fr - VocabLocalized',
@@ -18677,6 +18857,22 @@
   'plural' => '0',
   'i18n_status' => '0',
 ))
+->values(array(
+  'lid' => '79',
+  'translation' => 'Jupiter Station',
+  'language' => 'is',
+  'plid' => '0',
+  'plural' => '0',
+  'i18n_status' => '0',
+))
+->values(array(
+  'lid' => '80',
+  'translation' => 'is - Holographic research. (localized)',
+  'language' => 'is',
+  'plid' => '0',
+  'plural' => '0',
+  'i18n_status' => '0',
+))
 ->values(array(
   'lid' => '87',
   'translation' => 'is - VocabTranslate',
@@ -52532,29 +52728,29 @@
   'bootstrap' => '0',
   'schema_version' => '-1',
   'weight' => '0',
-  'info' => 'a:12:{s:4:"name";s:24:"Synchronize translations";s:11:"description";s:73:"Synchronizes taxonomy and fields across translations of the same content.";s:12:"dependencies";a:2:{i:0;s:4:"i18n";i:1;s:11:"translation";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:5:{i:0;s:16:"i18n_sync.module";i:1;s:17:"i18n_sync.install";i:2;s:20:"i18n_sync.module.inc";i:3;s:18:"i18n_sync.node.inc";i:4;s:14:"i18n_sync.test";}s:7:"version";s:8:"7.x-1.26";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1534531985";s:5:"mtime";i:1534531985;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+  'info' => 'a:12:{s:4:"name";s:24:"Synchronize translations";s:11:"description";s:73:"Synchronizes taxonomy and fields across translations of the same content.";s:12:"dependencies";a:2:{i:0;s:4:"i18n";i:1;s:11:"translation";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:5:{i:0;s:16:"i18n_sync.module";i:1;s:17:"i18n_sync.install";i:2;s:20:"i18n_sync.module.inc";i:3;s:18:"i18n_sync.node.inc";i:4;s:14:"i18n_sync.test";}s:7:"version";s:8:"7.x-1.25";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1531342125";s:5:"mtime";i:1537747251;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
 ))
 ->values(array(
   'filename' => 'sites/all/modules/i18n/i18n_taxonomy/i18n_taxonomy.module',
   'name' => 'i18n_taxonomy',
   'type' => 'module',
   'owner' => '',
-  'status' => '0',
+  'status' => '1',
   'bootstrap' => '0',
-  'schema_version' => '-1',
-  'weight' => '0',
-  'info' => 'a:12:{s:4:"name";s:20:"Taxonomy translation";s:11:"description";s:30:"Enables multilingual taxonomy.";s:12:"dependencies";a:3:{i:0;s:8:"taxonomy";i:1;s:11:"i18n_string";i:2;s:16:"i18n_translation";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:4:{i:0;s:17:"i18n_taxonomy.inc";i:1;s:23:"i18n_taxonomy.pages.inc";i:2;s:23:"i18n_taxonomy.admin.inc";i:3;s:18:"i18n_taxonomy.test";}s:7:"version";s:8:"7.x-1.26";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1534531985";s:5:"mtime";i:1534531985;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+  'schema_version' => '7004',
+  'weight' => '5',
+  'info' => 'a:12:{s:4:"name";s:20:"Taxonomy translation";s:11:"description";s:30:"Enables multilingual taxonomy.";s:12:"dependencies";a:3:{i:0;s:8:"taxonomy";i:1;s:11:"i18n_string";i:2;s:16:"i18n_translation";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:4:{i:0;s:17:"i18n_taxonomy.inc";i:1;s:23:"i18n_taxonomy.pages.inc";i:2;s:23:"i18n_taxonomy.admin.inc";i:3;s:18:"i18n_taxonomy.test";}s:7:"version";s:8:"7.x-1.25";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1531342125";s:5:"mtime";i:1537747251;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
 ))
 ->values(array(
   'filename' => 'sites/all/modules/i18n/i18n_translation/i18n_translation.module',
   'name' => 'i18n_translation',
   'type' => 'module',
   'owner' => '',
-  'status' => '0',
+  'status' => '1',
   'bootstrap' => '0',
   'schema_version' => '-1',
   'weight' => '0',
-  'info' => 'a:12:{s:4:"name";s:16:"Translation sets";s:11:"description";s:47:"Simple translation sets API for generic objects";s:12:"dependencies";a:1:{i:0;s:4:"i18n";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:1:{i:0;s:20:"i18n_translation.inc";}s:7:"version";s:8:"7.x-1.26";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1534531985";s:5:"mtime";i:1534531985;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
+  'info' => 'a:12:{s:4:"name";s:16:"Translation sets";s:11:"description";s:47:"Simple translation sets API for generic objects";s:12:"dependencies";a:1:{i:0;s:4:"i18n";}s:7:"package";s:35:"Multilingual - Internationalization";s:4:"core";s:3:"7.x";s:5:"files";a:1:{i:0;s:20:"i18n_translation.inc";}s:7:"version";s:8:"7.x-1.25";s:7:"project";s:4:"i18n";s:9:"datestamp";s:10:"1531342125";s:5:"mtime";i:1537747251;s:3:"php";s:5:"5.2.4";s:9:"bootstrap";i:0;}',
 ))
 ->values(array(
   'filename' => 'sites/all/modules/i18n/i18n_user/i18n_user.module',
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
index 865f11f2d0292ac4fa6aed06d09dcf128d651e41..7e7bd5502a4881a63386c014568a2beb60e446e7 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
@@ -185,6 +185,8 @@ protected function getMissingPaths() {
       'i18n',
       'i18n_field',
       'i18n_string',
+      'i18n_taxonomy',
+      'i18n_translation',
       'locale',
       'variable',
       'variable_realm',
diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d7/TermLocalizedTranslation.php b/core/modules/taxonomy/src/Plugin/migrate/source/d7/TermLocalizedTranslation.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d1c47d27feb426f62255cf9d2112740790a065f
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/migrate/source/d7/TermLocalizedTranslation.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace Drupal\taxonomy\Plugin\migrate\source\d7;
+
+use Drupal\content_translation\Plugin\migrate\source\I18nQueryTrait;
+use Drupal\migrate\Row;
+
+/**
+ * Gets i18n taxonomy terms from source database.
+ *
+ * @MigrateSource(
+ *   id = "d7_term_localized_translation",
+ *   source_module = "i18n_taxonomy"
+ * )
+ */
+class TermLocalizedTranslation extends Term {
+
+  use I18nQueryTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // Ideally, the query would return rows for each language for each taxonomy
+    // term with the translations for both the name and description or just the
+    // name translation or just the description translation. That query quickly
+    // became complex and would be difficult to maintain.
+    // Therefore, build a query based on i18nstrings table where each row has
+    // the translation for only one property, either name or description. The
+    // method prepareRow() is then used to obtain the translation for the other
+    // property.
+    $query = parent::query();
+    $query->addField('td', 'language', 'td.language');
+
+    // Add in the property, which is either name or description.
+    // Cast td.tid as char for PostgreSQL compatibility.
+    $query->leftJoin('i18n_string', 'i18n', 'CAST(td.tid AS CHAR(255)) = i18n.objectid');
+    $query->condition('i18n.type', 'term');
+    $query->isNotNull('i18n.lid');
+    $query->addField('i18n', 'lid');
+    $query->addField('i18n', 'property');
+
+    // Add in the translation for the property.
+    $query->innerJoin('locales_target', 'lt', 'i18n.lid = lt.lid');
+    $query->addField('lt', 'language', 'lt.language');
+    $query->addField('lt', 'translation');
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $language = $row->getSourceProperty('ltlanguage');
+    $tid = $row->getSourceProperty('tid');
+
+    // If this row has been migrated it is a duplicate then skip it.
+    if ($this->idMap->lookupDestinationIds(['tid' => $tid, 'language' => $language])) {
+      return FALSE;
+    }
+
+    // Save the translation for the property already in the row.
+    $property_in_row = $row->getSourceProperty('property');
+    $row->setSourceProperty($property_in_row . '_translated', $row->getSourceProperty('translation'));
+
+    // Get the translation for the property not already in the row and save it
+    // in the row.
+    $property_not_in_row = ($property_in_row == 'name') ? 'description' : 'name';
+
+    // Get the translation, if one exists, for the property not already in the
+    // row.
+    $query = $this->select('i18n_string', 'i18n')
+      ->fields('i18n', ['lid'])
+      ->condition('i18n.property', $property_not_in_row);
+    $query->leftJoin('locales_target', 'lt', 'i18n.lid = lt.lid');
+    $query->condition('lt.language', $language);
+    $query->addField('lt', 'translation');
+    $results = $query->execute()->fetchAssoc();
+    if (!$results) {
+      $row->setSourceProperty($property_not_in_row . '_translated', NULL);
+    }
+    else {
+      $row->setSourceProperty($property_not_in_row . '_translated', $results['translation']);
+    }
+    parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    $fields = [
+      'language' => $this->t('Language for this term.'),
+      'name_translated' => $this->t('Term name translation.'),
+      'description_translated' => $this->t('Term description translation.'),
+    ];
+    return parent::fields() + $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['language']['type'] = 'string';
+    $ids['language']['alias'] = 'lt';
+    return parent::getIds() + $ids;
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTermLocalizedTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTermLocalizedTranslationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..06da1ad1dff38793e7439d096fbf51583f281edb
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTermLocalizedTranslationTest.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Migrate\d7;
+
+use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
+use Drupal\taxonomy\Entity\Term;
+use Drupal\taxonomy\TermInterface;
+
+/**
+ * Tests migration of localized translated taxonomy terms.
+ *
+ * @group migrate_drupal_7
+ */
+class MigrateTermLocalizedTranslationTest extends MigrateDrupal7TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'content_translation',
+    'language',
+    // Required for translation migrations.
+    'migrate_drupal_multilingual',
+    'taxonomy',
+    'text',
+  ];
+
+  /**
+   * The cached taxonomy tree items, keyed by vid and tid.
+   *
+   * @var array
+   */
+  protected $treeData = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('taxonomy_term');
+    $this->installConfig(static::$modules);
+    $this->executeMigrations([
+      'language',
+      'd7_taxonomy_vocabulary',
+      'd7_taxonomy_term',
+      'd7_taxonomy_term_localized_translation',
+    ]);
+  }
+
+  /**
+   * Validates a migrated term contains the expected values.
+   *
+   * @param int $id
+   *   Entity ID to load and check.
+   * @param string $expected_language
+   *   The language code for this term.
+   * @param string $expected_label
+   *   The label the migrated entity should have.
+   * @param string $expected_vid
+   *   The parent vocabulary the migrated entity should have.
+   * @param string $expected_description
+   *   The description the migrated entity should have.
+   * @param string $expected_format
+   *   The format the migrated entity should have.
+   * @param int $expected_weight
+   *   The weight the migrated entity should have.
+   * @param array $expected_parents
+   *   The parent terms the migrated entity should have.
+   * @param int $expected_field_integer_value
+   *   The value the migrated entity field should have.
+   * @param int $expected_term_reference_tid
+   *   The term reference ID the migrated entity field should have.
+   */
+  protected function assertEntity($id, $expected_language, $expected_label, $expected_vid, $expected_description = '', $expected_format = NULL, $expected_weight = 0, array $expected_parents = [], $expected_field_integer_value = NULL, $expected_term_reference_tid = NULL) {
+    /** @var \Drupal\taxonomy\TermInterface $entity */
+    $entity = Term::load($id);
+    $this->assertInstanceOf(TermInterface::class, $entity);
+    $this->assertSame($expected_language, $entity->language()->getId());
+    $this->assertSame($expected_label, $entity->label());
+    $this->assertSame($expected_vid, $entity->bundle());
+    $this->assertSame($expected_description, $entity->getDescription());
+    $this->assertSame($expected_format, $entity->getFormat());
+    $this->assertSame($expected_weight, $entity->getWeight());
+    $this->assertHierarchy($expected_vid, $id, $expected_parents);
+  }
+
+  /**
+   * Asserts that a term is present in the tree storage, with the right parents.
+   *
+   * @param string $vid
+   *   Vocabulary ID.
+   * @param int $tid
+   *   ID of the term to check.
+   * @param array $parent_ids
+   *   The expected parent term IDs.
+   */
+  protected function assertHierarchy($vid, $tid, array $parent_ids) {
+    if (!isset($this->treeData[$vid])) {
+      $tree = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
+      $this->treeData[$vid] = [];
+      foreach ($tree as $item) {
+        $this->treeData[$vid][$item->tid] = $item;
+      }
+    }
+
+    $this->assertArrayHasKey($tid, $this->treeData[$vid], "Term $tid exists in taxonomy tree");
+    $term = $this->treeData[$vid][$tid];
+    $this->assertEquals($parent_ids, array_filter($term->parents), "Term $tid has correct parents in taxonomy tree");
+  }
+
+  /**
+   * Tests the Drupal 6 i18n localized taxonomy term to Drupal 8 migration.
+   */
+  public function testTranslatedLocalizedTaxonomyTerms() {
+    $this->assertEntity(19, 'en', 'Jupiter Station', 'vocablocalized', 'Holographic research.', 'filtered_html', '0', []);
+    $this->assertEntity(20, 'en', 'DS9', 'vocablocalized', 'Terok Nor', 'filtered_html', '0', []);
+
+    /** @var \Drupal\taxonomy\TermInterface $entity */
+    $entity = Term::load(19);
+    $this->assertFalse($entity->hasTranslation('fr'));
+    $this->assertTrue($entity->hasTranslation('is'));
+    $translation = $entity->getTranslation('is');
+    $this->assertSame('Jupiter Station', $translation->label());
+    $this->assertSame('is - Holographic research. (localized)', $translation->getDescription());
+
+    $entity = Term::load(20);
+    $this->assertFalse($entity->hasTranslation('is'));
+    $this->assertTrue($entity->hasTranslation('fr'));
+    $translation = $entity->getTranslation('fr');
+    $this->assertSame('fr - DS9 (localized)', $translation->label());
+    $this->assertSame('fr - Terok Nor (localized)', $translation->getDescription());
+    $this->assertFALSE($entity->hasTranslation('is'));
+  }
+
+}