diff --git a/core/modules/config_translation/migration_templates/d6_i18n_taxonomy_vocabulary.yml b/core/modules/config_translation/migration_templates/d6_i18n_taxonomy_vocabulary.yml
new file mode 100644
index 0000000..c5b716e
--- /dev/null
+++ b/core/modules/config_translation/migration_templates/d6_i18n_taxonomy_vocabulary.yml
@@ -0,0 +1,25 @@
+id: d6_i18n_taxonomy_vocabulary
+label: Taxonomy vocabularies
+migration_tags:
+  - Drupal 6
+source:
+  plugin: d6_i18n_taxonomy_vocabulary
+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
+
diff --git a/core/modules/config_translation/src/Plugin/migrate/destination/I18nTaxonomyVocabulary.php b/core/modules/config_translation/src/Plugin/migrate/destination/I18nTaxonomyVocabulary.php
new file mode 100644
index 0000000..db507a9
--- /dev/null
+++ b/core/modules/config_translation/src/Plugin/migrate/destination/I18nTaxonomyVocabulary.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\config_translation\Plugin\migrate\destination\I18nTaxonomyVocabulary.
+ */
+
+namespace Drupal\config_translation\Plugin\migrate\destination;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\migrate\Entity\MigrationInterface;
+use Drupal\migrate\Row;
+use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
+
+/**
+ * Persist TaxonomyVocabulary data to the config system.
+ *
+ * @MigrateDestination(
+ *   id = "i18n_taxonomy_vocabulary"
+ * )
+ */
+class I18nTaxonomyVocabulary extends DestinationBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $config_factory;
+
+  /**
+   * Constructs a TaxonomyVocabulary object.
+   *
+   * @param array $configuration
+   *   Plugin configuration.
+   * @param string $plugin_id
+   *   The plugin ID.
+   * @param mixed $plugin_definition
+   *   The plugin definition.
+   * @param \Drupal\migrate\Entity\MigrationInterface $migration
+   *   The current migration.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, ConfigFactoryInterface $config_factory) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
+    $this->config_factory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $migration,
+      $container->get('config.factory')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function import(Row $row, array $old_destination_id_values = array()) {
+    $value = $row->getDestinationProperty('value');
+    if (isset($value)) {
+      $config = $this->config_factory->getEditable($row->getDestinationProperty('configuration_name'));
+      $config->set($row->getDestinationProperty('element_name'), $row->getDestinationProperty('value'));
+      $config->save();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['name']['type'] = 'string';
+    return $ids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields(MigrationInterface $migration = NULL) {
+  }
+
+}
diff --git a/core/modules/config_translation/src/Plugin/migrate/process/Substr.php b/core/modules/config_translation/src/Plugin/migrate/process/Substr.php
new file mode 100644
index 0000000..74f335d
--- /dev/null
+++ b/core/modules/config_translation/src/Plugin/migrate/process/Substr.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_translation\Plugin\migrate\process\Substr.
+ */
+
+namespace Drupal\config_translation\Plugin\migrate\process;
+
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Row;
+use Drupal\migrate\MigrateException;
+use Drupal\Component\Utility\Unicode;
+
+/**
+ * Gets a substring.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "substr"
+ * )
+ */
+
+class Substr extends ProcessPluginBase {
+
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $start = isset($this->configuration['start']) ? $this->configuration['start'] : 0;
+    if (!is_int($start)) {
+      throw new MigrateException('The start position configuration key should be an integer. Omit this key to capture from the beginning of the string.');
+    }
+    $length = isset($this->configuration['length']) ? $this->configuration['length'] : NULL;
+    if (!is_null($length) && !is_int($length)) {
+      throw new MigrateException('The character length configuration key should be an integer. Omit this key to capture the entire string.');
+    }
+    // Use optional start or length to return a portion of $value.
+    $new_value = Unicode::substr($value, $start, $length);
+    return $new_value;
+  }
+
+}
diff --git a/core/modules/config_translation/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php b/core/modules/config_translation/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php
new file mode 100644
index 0000000..c72740d
--- /dev/null
+++ b/core/modules/config_translation/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_translation\Plugin\migrate\source\d6\I18nTaxonomyVocabulary.
+ */
+
+namespace Drupal\config_translation\Plugin\migrate\source\d6;
+
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+use Drupal\migrate\Row;
+
+/**
+ * Profile field source from database.
+ *
+ * @MigrateSource(
+ *   id = "d6_i18n_taxonomy_vocabulary",
+ *   source_provider = "taxonomy"
+ * )
+ */
+class i18nTaxonomyVocabulary extends DrupalSqlBase {
+
+  /**
+   * The source table containing profile field info.
+   *
+   * @var string
+   */
+  protected $fieldTable;
+
+  /**
+   * The source table containing the profile values.
+   *
+   * @var string
+   */
+  protected $valueTable;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $query = $this->select('vocabulary', 'v')
+      ->fields('v', array('vid', 'name', 'description'))
+      ->fields('i18n', array('lid', 'type', 'property', 'objectid'))
+      ->fields('lt', array('lid', 'translation'))
+      ->condition('i18n.type', 'vocabulary');
+    $query->addField('lt', 'language', 'language');
+    $query->Join('i18n_strings', 'i18n', 'i18n.objectid = v.vid');
+    $query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
+    return $query;
+  }
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      '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/config_translation/src/Tests/Migrate/d6/MigrateI18nTaxonomyVocabularyTest.php b/core/modules/config_translation/src/Tests/Migrate/d6/MigrateI18nTaxonomyVocabularyTest.php
new file mode 100644
index 0000000..d9a1229
--- /dev/null
+++ b/core/modules/config_translation/src/Tests/Migrate/d6/MigrateI18nTaxonomyVocabularyTest.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_translation\Tests\Migrate\d6\MigrateI18nTaxonomyVocabularyTest.
+ */
+
+namespace Drupal\config_translation\Tests\Migrate\d6;
+
+use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
+
+/**
+ * Tests the user profile field instance migration.
+ *
+ * @group migrate_drupal_6
+ */
+class MigrateI18nTaxonomyVocabularyTest extends MigrateDrupal6TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['config_translation', 'locale', 'language', 'taxonomy'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->executeMigration('d6_taxonomy_vocabulary');
+    $this->executeMigration('d6_i18n_taxonomy_vocabulary');
+  }
+
+  /**
+   * Tests the Drupal 6 taxonomy vocabularies to Drupal 8 migration.
+   */
+  public function testTaxonomyVocabulary() {
+    $config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_1_i_0_');
+    $this->assertIdentical('fr - vocabulary 1 (i=0)', $config->get('name'));
+    $config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_2_i_1_');
+    $this->assertIdentical('fr - vocabulary 2 (i=1)', $config->get('name'));
+    $config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_3_i_2_');
+    $this->assertIdentical('fr - vocabulary 3 (i=2)', $config->get('name'));
+    $config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_name_much_longer_than');
+    $this->assertIdentical('Nom de vocabulaire beaucoup plus long que trente-deux caractères', $config->get('name'));
+    $config = \Drupal::service('language_manager')->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.tags');
+    $this->assertIdentical('fr - Tags', $config->get('name'));
+  }
+
+}
