diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 5360edd..b53d139 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -237,7 +237,6 @@ public function save() {
    *   The configuration object.
    */
   public function delete() {
-    // @todo Consider to remove the pruning of data for Config::delete().
     $this->data = array();
     $this->storage->delete($this->name);
     $this->isNew = TRUE;
diff --git a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
index df1b335..e90a058 100644
--- a/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/DefaultConfigTest.php
@@ -51,9 +51,9 @@ public function testDefaultConfig() {
     $default_config_storage = new TestInstallStorage();
 
     foreach ($default_config_storage->listAll() as $config_name) {
-      // @todo: remove once migration (https://drupal.org/node/2183957) and
-      // translation (https://drupal.org/node/2168609) schemas are in.
-      if (strpos($config_name, 'migrate.migration') === 0 || strpos($config_name, 'language.config') === 0) {
+      // @todo: remove once migration (https://drupal.org/node/2183957) schemas
+      // are in.
+      if (strpos($config_name, 'migrate.migration') === 0) {
         continue;
       }
 
diff --git a/core/modules/config/tests/config_test/config/install/language.config.de.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/de/config_test.system.yml
similarity index 100%
rename from core/modules/config/tests/config_test/config/install/language.config.de.config_test.system.yml
rename to core/modules/config/tests/config_test/config/install/language/de/config_test.system.yml
diff --git a/core/modules/config/tests/config_test/config/install/language.config.en.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/en/config_test.system.yml
similarity index 100%
rename from core/modules/config/tests/config_test/config/install/language.config.en.config_test.system.yml
rename to core/modules/config/tests/config_test/config/install/language/en/config_test.system.yml
diff --git a/core/modules/config/tests/config_test/config/install/language.config.fr.config_test.system.yml b/core/modules/config/tests/config_test/config/install/language/fr/config_test.system.yml
similarity index 100%
rename from core/modules/config/tests/config_test/config/install/language.config.fr.config_test.system.yml
rename to core/modules/config/tests/config_test/config/install/language/fr/config_test.system.yml
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
index fb3ba88..13311d9 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
@@ -15,6 +15,7 @@
 use Drupal\Core\Form\BaseFormIdInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Language\Language;
+use Drupal\language\Config\LanguageConfigOverride;
 use Drupal\language\ConfigurableLanguageManagerInterface;
 use Drupal\locale\StringStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -352,7 +353,7 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
    *   Set the configuration in this language.
    * @param \Drupal\Core\Config\Config $base_config
    *   Base configuration values, in the source language.
-   * @param \Drupal\Core\Config\Config $config_translation
+   * @param \Drupal\language\Config\LanguageConfigOverride $config_translation
    *   Translation configuration override data.
    * @param array $config_values
    *   A simple one dimensional or recursive array:
@@ -372,7 +373,7 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
    * @return array
    *   Translation configuration override data.
    */
-  protected function setConfig(Language $language, Config $base_config, Config $config_translation, array $config_values, $shipped_config = FALSE) {
+  protected function setConfig(Language $language, Config $base_config, LanguageConfigOverride $config_translation, array $config_values, $shipped_config = FALSE) {
     foreach ($config_values as $key => $value) {
       if (is_array($value) && !isset($value['translation'])) {
         // Traverse into this level in the configuration.
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index f35da4d..6a71fc7 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -441,6 +441,8 @@ function language_save($language) {
   $language_entity->save();
   $t_args = array('%language' => $language->name, '%langcode' => $language->id);
   if ($language->is_new) {
+    // Install any available language configuration overrides for the language.
+    \Drupal::service('language.config_factory_override')->installLanguageOverrides($language->getId());
     watchdog('language', 'The %language (%langcode) language has been created.', $t_args);
   }
   else {
diff --git a/core/modules/language/language.services.yml b/core/modules/language/language.services.yml
index 7396d57..e183e6d 100644
--- a/core/modules/language/language.services.yml
+++ b/core/modules/language/language.services.yml
@@ -16,3 +16,4 @@ services:
     arguments: ['@config.storage', '@event_dispatcher', '@config.typed']
     tags:
       - { name: config.factory.override, priority: -254 }
+      - { name: event_subscriber }
diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php
index bfadec0..8492a97 100644
--- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php
+++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverride.php
@@ -7,24 +7,36 @@
 
 namespace Drupal\language\Config;
 
-use Drupal\Core\Config\Config;
+use Drupal\Core\Config\ConfigCollectionNamesEvent;
+use Drupal\Core\Config\ConfigEvents;
 use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageDefault;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
  * Provides language overrides for the configuration factory.
  */
-class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInterface {
+class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInterface, EventSubscriberInterface {
 
   /**
    * The configuration storage.
    *
+   * Do not access this directly. Should be accessed through self::getStorage()
+   * so that the cache of storages per langcode is used.
+   *
    * @var \Drupal\Core\Config\StorageInterface
    */
-  protected $storage;
+  protected $baseStorage;
+
+  /**
+   * An array of configuration storages keyed by langcode.
+   *
+   * @var \Drupal\Core\Config\StorageInterface[]
+   */
+  protected $storages;
 
   /**
    * The typed config manager.
@@ -58,7 +70,7 @@ class LanguageConfigFactoryOverride implements LanguageConfigFactoryOverrideInte
    *   The typed configuration manager.
    */
   public function __construct(StorageInterface $storage, EventDispatcherInterface $event_dispatcher, TypedConfigManagerInterface $typed_config) {
-    $this->storage = $storage;
+    $this->baseStorage = $storage;
     $this->eventDispatcher = $event_dispatcher;
     $this->typedConfigManager = $typed_config;
   }
@@ -67,72 +79,34 @@ public function __construct(StorageInterface $storage, EventDispatcherInterface
    * {@inheritdoc}
    */
   public function loadOverrides($names) {
-    $data = array();
-    $language_names = $this->getLanguageConfigNames($names);
-    if ($language_names) {
-      $data = $this->storage->readMultiple(array_values($language_names));
-      // Re-key the data array to use configuration names rather than override
-      // names.
-      $prefix_length = strlen(static::LANGUAGE_CONFIG_PREFIX . '.' . $this->language->id) + 1;
-      foreach ($data as $key => $value) {
-        unset($data[$key]);
-        $key = substr($key, $prefix_length);
-        $data[$key] = $value;
-      }
+    if ($this->language) {
+      $storage = $this->getStorage($this->language->getId());
+      return $storage->readMultiple($names);
     }
-    return $data;
+    return array();
   }
 
   /**
    * {@inheritdoc}
    */
   public function getOverride($langcode, $name) {
-    $override_name = $this->getLanguageConfigName($langcode, $name);
-    $overrides = $this->storage->read($override_name);
-    $config = new Config($override_name, $this->storage, $this->eventDispatcher, $this->typedConfigManager);
-    if (!empty($overrides)) {
-      $config->initWithData($overrides);
+    $storage = $this->getStorage($langcode);
+    $data = $storage->read($name);
+    $override = new LanguageConfigOverride($name, $storage, $this->typedConfigManager);
+    if (!empty($data)) {
+      $override->initWithData($data);
     }
-    return $config;
+    return $override;
   }
 
   /**
-   * Generate a list of configuration names based on base names.
-   *
-   * @param array $names
-   *   List of configuration names.
-   *
-   * @return array
-   *   List of configuration names for language override files if applicable.
-   */
-  protected function getLanguageConfigNames(array $names) {
-    $language_names = array();
-    if (isset($this->language)) {
-      foreach ($names as $name) {
-        if ($language_name = $this->getLanguageConfigName($this->language->id, $name)) {
-          $language_names[$name] = $language_name;
-        }
-      }
-    }
-    return $language_names;
-  }
-
-  /**
-   * Get language override name for given language and configuration name.
-   *
-   * @param string $langcode
-   *   Language code.
-   * @param string $name
-   *   Configuration name.
-   *
-   * @return bool|string
-   *   Configuration name or FALSE if not applicable.
+   * {@inheritdoc}
    */
-  protected function getLanguageConfigName($langcode, $name) {
-     if (strpos($name, static::LANGUAGE_CONFIG_PREFIX) === 0) {
-      return FALSE;
+  public function getStorage($langcode) {
+    if (!isset($this->storages[$langcode])) {
+      $this->storages[$langcode] = $this->baseStorage->createCollection($this->createConfigCollectionName($langcode));
     }
-    return static::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.' . $name;
+    return $this->storages[$langcode];
   }
 
   /**
@@ -165,4 +139,48 @@ public function setLanguageFromDefault(LanguageDefault $language_default = NULL)
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function installLanguageOverrides($langcode) {
+    /** @var \Drupal\Core\Config\ConfigInstallerInterface $config_installer */
+    $config_installer = \Drupal::service('config.installer');
+    $config_installer->installCollectionDefaultConfig($this->createConfigCollectionName($langcode));
+  }
+
+  /**
+   * Creates a configuration collection name based on a langcode.
+   *
+   * @param string $langcode
+   *   The langcode.
+   *
+   * @return string
+   *   The configuration collection name for a langcode.
+   */
+  protected function createConfigCollectionName($langcode) {
+    return 'language.' . $langcode;
+  }
+
+  /**
+   * Reacts to the ConfigEvents::COLLECTION_NAMES event.
+   *
+   * @param \Drupal\Core\Config\ConfigCollectionNamesEvent $event
+   *   The configuration collection names event.
+   */
+  public function addCollectionNames(ConfigCollectionNamesEvent $event) {
+    $collections = array();
+    foreach (\Drupal::languageManager()->getLanguages() as $language) {
+      $collections[] = $this->createConfigCollectionName($language->getId());
+    }
+    $event->addCollectionNames($collections);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getSubscribedEvents() {
+    $events[ConfigEvents::COLLECTION_NAMES][] = array('addCollectionNames');
+    return $events;
+  }
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php
index 1c3de55..1d3a43b 100644
--- a/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php
+++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigFactoryOverrideInterface.php
@@ -17,11 +17,6 @@
 interface LanguageConfigFactoryOverrideInterface extends ConfigFactoryOverrideInterface {
 
   /**
-   * Prefix for all language configuration files.
-   */
-  const LANGUAGE_CONFIG_PREFIX = 'language.config';
-
-  /**
    * Gets the language object used to override configuration data.
    *
    * @return \Drupal\Core\Language\Language
@@ -62,4 +57,23 @@ public function setLanguageFromDefault(LanguageDefault $language_default = NULL)
    */
   public function getOverride($langcode, $name);
 
+  /**
+   * Returns the storage instance for a particular langcode.
+   *
+   * @param string $langcode
+   *   Language code.
+   *
+   * @return \Drupal\language\Config\LanguageOverrideStorageInterface
+   *   The language override storage object.
+   */
+  public function getStorage($langcode);
+
+  /**
+   * Installs available language configuration overrides for a given langcode.
+   *
+   * @param string $langcode
+   *   Language code.
+   */
+  public function installLanguageOverrides($langcode);
+
 }
diff --git a/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php
new file mode 100644
index 0000000..19fb549
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Config/LanguageConfigOverride.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Config\LanguageConfigOverride.
+ */
+
+namespace Drupal\language\Config;
+
+use Drupal\Core\Config\StorableConfigBase;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\Core\Config\TypedConfigManagerInterface;
+
+/**
+ * Defines language configuration overrides.
+ */
+class LanguageConfigOverride extends StorableConfigBase {
+
+  /**
+   * Constructs a language override object.
+   *
+   * @param string $name
+   *   The name of the configuration object being overridden.
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   A storage controller object to use for reading and writing the
+   *   configuration override.
+   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
+   *   The typed configuration manager service.
+   */
+  public function __construct($name, StorageInterface $storage, TypedConfigManagerInterface $typed_config) {
+    $this->name = $name;
+    $this->storage = $storage;
+    $this->typedConfigManager = $typed_config;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save() {
+    // @todo Use configuration schema to validate.
+    //   https://drupal.org/node/2270399
+    // Perform basic data validation.
+    foreach ($this->data as $key => $value) {
+      $this->validateValue($key, $value);
+    }
+    $this->storage->write($this->name, $this->data);
+    $this->isNew = FALSE;
+    $this->originalData = $this->data;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete() {
+    $this->data = array();
+    $this->storage->delete($this->name);
+    $this->isNew = TRUE;
+    $this->originalData = $this->data;
+    return $this;
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
index 101449c..b28e02b 100644
--- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
+++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
@@ -410,6 +410,13 @@ public function getLanguageConfigOverride($langcode, $name) {
   /**
    * {@inheritdoc}
    */
+  public function getLanguageConfigOverrideStorage($langcode) {
+    return $this->configFactoryOverride->getStorage($langcode);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getStandardLanguageListWithoutConfigured() {
     $languages = $this->getLanguages();
     $predefined = $this->getStandardLanguageList();
diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php
index 9bbf2ce..f02e0ef 100644
--- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php
+++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManagerInterface.php
@@ -91,12 +91,24 @@ public function updateLockedLanguageWeights();
    * @param string $name
    *   The language configuration object name.
    *
-   * @return \Drupal\Core\Config\Config
+   * @return \Drupal\language\Config\LanguageConfigOverride
    *   The language config override object.
    */
   public function getLanguageConfigOverride($langcode, $name);
 
   /**
+   * Gets a language configuration override storage object.
+   *
+   * @param string $langcode
+   *   The language code for the override.
+   *
+   * @param \Drupal\Core\Config\StorageInterface $storage
+   *   A storage object to use for reading and writing the
+   *   configuration override.
+   */
+  public function getLanguageConfigOverrideStorage($langcode);
+
+  /**
    * Returns the standard language list excluding already configured languages.
    *
    * @return array
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php
new file mode 100644
index 0000000..9df51e3
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageConfigOverrideImportTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Tests\LanguageConfigOverrideImportTest.
+ */
+
+namespace Drupal\language\Tests;
+
+use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Language\Language;
+use Drupal\simpletest\WebTestBase;
+
+class LanguageConfigOverrideImportTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('language', 'config', 'locale', 'config_translation');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Language config override synchronize',
+      'description' => 'Ensures the language config overrides can be synchronized.',
+      'group' => 'Language',
+    );
+  }
+
+  /**
+   *
+   */
+  public function testConfigOverrideImport() {
+    language_save(new Language(array(
+      'name' => 'French',
+      'id' => 'fr',
+    )));
+    /* @var \Drupal\Core\Config\StorageInterface $staging */
+    $staging = \Drupal::service('config.storage.staging');
+    $this->copyConfig(\Drupal::service('config.storage'), $staging);
+
+    \Drupal::moduleHandler()->uninstall(array('language'));
+    // Ensure that the current site has no overrides registered to the
+    // ConfigFactory.
+    $this->rebuildContainer();
+
+    /* @var \Drupal\Core\Config\StorageInterface $override_staging */
+    $override_staging = new FileStorage(config_get_config_directory(CONFIG_STAGING_DIRECTORY) . '/language/fr');
+    // Create some overrides in staging.
+    $override_staging->write('system.site', array('name' => 'FR default site name'));
+    $override_staging->write('system.maintenance', array('message' => 'FR message: @site is currently under maintenance. We should be back shortly. Thank you for your patience'));
+
+    $this->configImporter()->import();
+    $this->rebuildContainer();
+    \Drupal::service('router.builder')->rebuild();
+
+    $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site');
+    $this->assertEqual('FR default site name', $override->get('name'));
+    $this->drupalGet('fr');
+    $this->assertText('FR default site name');
+
+    $this->drupalLogin($this->root_user);
+    $this->drupalGet('admin/config/development/maintenance/translate/fr/edit');
+    $this->assertText('FR message: @site is currently under maintenance. We should be back shortly. Thank you for your patience');
+  }
+}
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
index 3c0dc57..f731b13 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigManager.php
@@ -230,9 +230,9 @@ public function getStringNames(array $lids) {
    *   Language code to delete.
    */
   public function deleteLanguageTranslations($langcode) {
-    $locale_name = LanguageConfigFactoryOverrideInterface::LANGUAGE_CONFIG_PREFIX . '.' . $langcode . '.';
-    foreach ($this->configStorage->listAll($locale_name) as $name) {
-      $this->configStorage->delete($name);
+    $storage = $this->languageManager->getLanguageConfigOverrideStorage($langcode);
+    foreach ($storage->listAll() as $name) {
+      $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete();
     }
   }
 
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
index bdde87f..50cbc7d 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleConfigManagerTest.php
@@ -42,7 +42,7 @@ public function testHasTranslation() {
     $this->installConfig(array('locale_test'));
     $locale_config_manager = \Drupal::service('locale.config.typed');
 
-    $language = new Language(array('id' => 'de'));
+    $language = language_save(new Language(array('id' => 'de')));
     $result = $locale_config_manager->hasTranslation('locale_test.no_translation', $language);
     $this->assertFalse($result, 'There is no translation for locale_test.no_translation configuration.');
 
diff --git a/core/modules/locale/tests/modules/locale_test/config/install/language.config.de.locale_test.translation.yml b/core/modules/locale/tests/modules/locale_test/config/install/language/de/locale_test.translation.yml
similarity index 100%
rename from core/modules/locale/tests/modules/locale_test/config/install/language.config.de.locale_test.translation.yml
rename to core/modules/locale/tests/modules/locale_test/config/install/language/de/locale_test.translation.yml
diff --git a/core/modules/system/tests/modules/menu_test/config/install/language.config.nl.menu_test.menu_item.yml b/core/modules/system/tests/modules/menu_test/config/install/language/nl/menu_test.menu_item.yml
similarity index 100%
rename from core/modules/system/tests/modules/menu_test/config/install/language.config.nl.menu_test.menu_item.yml
rename to core/modules/system/tests/modules/menu_test/config/install/language/nl/menu_test.menu_item.yml
diff --git a/core/modules/tour/tests/tour_test/config/install/language.config.it.tour.tour.tour-test.yml b/core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml
similarity index 100%
rename from core/modules/tour/tests/tour_test/config/install/language.config.it.tour.tour.tour-test.yml
rename to core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml
