diff --git a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
index 27e0146016..aacc6f01a9 100644
--- a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
+++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php
@@ -534,6 +534,10 @@ class MigrateUpgradeForm extends ConfirmFormBase {
       'source_module' => 'taxonomy',
       'destination_module' => 'taxonomy',
     ],
+    'd6_taxonomy_vocabulary_translation' => [
+      'source_module' => 'i18n',
+      'destination_module' => 'taxonomy',
+    ],
     'd6_term_node' => [
       'source_module' => 'taxonomy',
       'destination_module' => 'taxonomy',
diff --git a/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml
new file mode 100644
index 0000000000..dbb1793f97
--- /dev/null
+++ b/core/modules/taxonomy/migration_templates/d6_taxonomy_vocabulary_translation.yml
@@ -0,0 +1,27 @@
+id: d6_taxonomy_vocabulary_translation
+label: Taxonomy vocabularies
+migration_tags:
+  - Drupal 6
+source:
+  plugin: d6_taxonomy_vocabulary_translation
+process:
+  vid:
+    -
+      plugin: machine_name
+      source: name
+    -
+      plugin: substr
+      length: 32
+  langcode: language
+  property:
+    plugin: static_map
+    source: property
+    map:
+      name: name
+      description: description
+  translation: translation
+destination:
+  plugin: entity:taxonomy_vocabulary
+migration_dependencies:
+  required:
+    - d6_taxonomy_vocabulary
diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/TaxonomyVocabularyTranslation.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TaxonomyVocabularyTranslation.php
new file mode 100644
index 0000000000..49e0f42185
--- /dev/null
+++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/TaxonomyVocabularyTranslation.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\taxonomy\Plugin\migrate\source\d6;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Profile field source from database.
+ *
+ * @MigrateSource(
+ *   id = "d6_taxonomy_vocabulary_translation",
+ *   source_provider = "taxonomy"
+ * )
+ */
+class TaxonomyVocabularyTranslation extends DrupalSqlBase {
+
+  /**
+   * The source table containing field info.
+   *
+   * @var string
+   */
+  protected $fieldTable;
+
+  /**
+   * The source table containing the field values.
+   *
+   * @var string
+   */
+  protected $valueTable;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('vocabulary', 'v')
+      ->fields('v', ['vid', 'name', 'description'])
+      ->fields('i18n', ['lid', 'type', 'property', 'objectid'])
+      ->fields('lt', ['lid', 'translation'])
+      ->condition('i18n.type', 'vocabulary');
+    $query->addField('lt', 'language', 'language');
+    // The i18n_strings table has two columns containing the object ID, objectid
+    // and objectindex. The objectid column is a text field. Therefore, for the
+    // join to work in PostgreSQL, use the objectindex field as this is numeric
+    // like the vid field.
+    $query->join('i18n_strings', 'i18n', 'v.vid = i18n.objectindex');
+    $query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
+
+    return $query;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return [
+      'vid' => $this->t('The vocabulary ID.'),
+      'language' => $this->t('Language for this field.'),
+      'property' => $this->t('Name of property being translated.'),
+      'translation' => $this->t('Translation of either the title or explanation.'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['vid']['type'] = 'integer';
+    return $ids;
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php
new file mode 100644
index 0000000000..3993abb98f
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTranslationTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Migrate\d6;
+
+use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
+
+/**
+ * Migrate taxonomy vocabularies to taxonomy.vocabulary.*.yml.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateTaxonomyVocabularyTranslationTest extends MigrateDrupal6TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['language', 'taxonomy'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->executeMigrations([
+      'd6_taxonomy_vocabulary',
+      'd6_taxonomy_vocabulary_translation',
+    ]);
+  }
+
+  /**
+   * Tests the Drupal 6 i18n taxonomy vocabularies to Drupal 8 migration.
+   */
+  public function testTaxonomyVocabularyTranslation() {
+    $language_manager = \Drupal::service('language_manager');
+    $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_1_i_0_');
+    $this->assertSame('fr - vocabulary 1 (i=0)', $config->get('name'));
+    $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_2_i_1_');
+    $this->assertSame('fr - vocabulary 2 (i=1)', $config->get('name'));
+    $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_3_i_2_');
+    $this->assertSame('fr - vocabulary 3 (i=2)', $config->get('name'));
+    $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_name_much_longer_than');
+    $this->assertSame('Nom de vocabulaire beaucoup plus long que trente-deux caractères', $config->get('name'));
+    $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.tags');
+    $this->assertSame('fr - Tags', $config->get('name'));
+  }
+
+}
diff --git a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php
new file mode 100644
index 0000000000..f3acec32e2
--- /dev/null
+++ b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/VocabularyTranslationTest.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Drupal\Tests\taxonomy\Kernel\Plugin\migrate\source\d6;
+
+use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
+
+/**
+ * Tests D6 i18n vocabulary source plugin.
+ *
+ * @covers \Drupal\taxonomy\Plugin\migrate\source\d6\TaxonomyVocabularyTranslation
+ * @group taxonomy
+ */
+class VocabularyTranslationTest extends MigrateSqlSourceTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['taxonomy', 'migrate_drupal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function providerSource() {
+    $tests = [];
+
+    // The source data.
+    $tests[0][0]['i18n_strings'] = [
+      [
+        'lid' => 1,
+        'objectid' => 1,
+        'type' => 'vocabulary',
+        'property' => 'name',
+        'objectindex' => 1,
+        'format' => 0,
+      ],
+      [
+        'lid' => 2,
+        'objectid' => 2,
+        'type' => 'vocabulary',
+        'property' => 'name',
+        'objectindex' => 2,
+        'format' => 0,
+      ],
+    ];
+
+    $tests[0][0]['locales_target'] = [
+      [
+        'lid' => 1,
+        'language' => 'fr',
+        'translation' => 'fr - vocabulary 1',
+        'plid' => 0,
+        'plural' => 0,
+        'i18n_status' => 0,
+      ],
+      [
+        'lid' => 2,
+        'language' => 'fr',
+        'translation' => 'fr - vocabulary 2',
+        'plid' => 0,
+        'plural' => 0,
+        'i18n_status' => 0,
+      ],
+    ];
+
+    $tests[0][0]['vocabulary'] = [
+      [
+        'vid' => 1,
+        'name' => 'vocabulary 1',
+        'description' => 'description of vocabulary 1',
+        'help' => 1,
+        'relations' => 1,
+        'hierarchy' => 1,
+        'multiple' => 0,
+        'required' => 0,
+        'tags' => 0,
+        'module' => 'taxonomy',
+        'weight' => 4,
+        'language' => '',
+      ],
+      [
+        'vid' => 2,
+        'name' => 'vocabulary 2',
+        'description' => 'description of vocabulary 2',
+        'help' => 1,
+        'relations' => 1,
+        'hierarchy' => 1,
+        'multiple' => 0,
+        'required' => 0,
+        'tags' => 0,
+        'module' => 'taxonomy',
+        'weight' => 5,
+        'language' => '',
+      ],
+    ];
+
+    $tests[0]['expected_results'] = [
+      [
+        'vid' => 1,
+        'name' => 'vocabulary 1',
+        'description' => 'description of vocabulary 1',
+        'lid' => '1',
+        'type' => 'vocabulary',
+        'property' => 'name',
+        'objectid' => '1',
+        'lt_lid' => '1',
+        'translation' => 'fr - vocabulary 1',
+        'language' => 'fr',
+      ],
+      [
+        'vid' => 2,
+        'name' => 'vocabulary 2',
+        'description' => 'description of vocabulary 2',
+        'lid' => '2',
+        'type' => 'vocabulary',
+        'property' => 'name',
+        'objectid' => '2',
+        'lt_lid' => '2',
+        'translation' => 'fr - vocabulary 2',
+        'language' => 'fr',
+      ],
+    ];
+    return $tests;
+  }
+
+}
