diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php
index 3712fc3..20ef9f0 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLocaleOverride.php
@@ -150,6 +150,75 @@ function testConfigLocaleUserOverride() {
   }
 
   /**
+   * Tests locale override based on language.
+   */
+  function testConfigLocaleLanguageOverride() {
+    $this->installSchema('system', 'variable');
+    $this->installSchema('language', 'language');
+    language_save(new Language(array(
+      'name' => 'French',
+      'langcode' => 'fr',
+    )));
+    language_save(new Language(array(
+      'name' => 'English',
+      'langcode' => 'en',
+    )));
+    language_save(new Language(array(
+      'name' => 'German',
+      'langcode' => 'de',
+    )));
+
+    $language = language_load('fr');
+    $language_config_context = config_context_enter('Drupal\language\LanguageConfigContext');
+    $language_config_context->setLanguage($language);
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'fr bar');
+    // Ensure the non-overridden value is still the same.
+    $this->assertIdentical($config->get('404'), 'herp');
+
+    // Ensure that we get the expected value when we leave the language context. The
+    // locale overrides contain an English override too, so although we are not
+    // in a language override context, the English language override
+    // applies due to the negotiated language for the page.
+    config_context_leave();
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'en bar');
+
+    $config_factory = \Drupal::service('config.factory');
+    $language = language_load('de');
+    $config_factory->enterContext($language_config_context->setLanguage($language));
+    // Should not have to re-initialize the configuration object to get new
+    // overrides as the new context will have a different uuid.
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'de bar');
+
+    // Enter an english context on top of the german context.
+    $language = language_load('en');
+    // Create a new language config context to stack on top of the existing one.
+    $en_language_config_context = config_context_enter('Drupal\language\LanguageConfigContext');
+    $en_language_config_context->setLanguage($language);
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'en bar');
+
+    // Ensure that we get the expected value when we leave the english
+    // language context.
+    config_context_leave();
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'de bar');
+
+    // Ensure that we get the expected value when we leave the german
+    // language context.
+    config_context_leave();
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'en bar');
+
+    // Ensure that we cannot leave the default context.
+    config_context_leave();
+    $config = config('config_test.system');
+    $this->assertIdentical($config->get('foo'), 'en bar');
+  }
+
+  /**
    * Tests locale override in combination with global overrides.
    */
   function testConfigLocaleUserAndGlobalOverride() {
diff --git a/core/modules/language/lib/Drupal/language/LanguageConfigContext.php b/core/modules/language/lib/Drupal/language/LanguageConfigContext.php
new file mode 100644
index 0000000..58b83a6
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/LanguageConfigContext.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\LanguageConfigContext.
+ */
+
+namespace Drupal\language;
+
+use Drupal\Core\Config\Context\ConfigContext;
+use Drupal\Core\Language\Language;
+
+
+/**
+ * Defines a configuration context object for a language.
+ *
+ * This should be used when configuration objects need a context for a language
+ * other than the current language.
+ *
+ */
+class LanguageConfigContext extends ConfigContext {
+
+  /**
+   * Predefined key for language object.
+   */
+  const LANGUAGE_KEY = 'language';
+
+  /**
+   * Creates the configuration context for language.
+   *
+   * @param \Drupal\Core\Language\Language $language
+   *   The language to add to the config context.
+   *
+   * @return \Drupal\Core\Language\Language
+   *   The language config context object.
+   */
+  public function setLanguage(Language $language) {
+    $this->set(self::LANGUAGE_KEY, $language);
+    // Re-initialize since the language change changes the context fundamentally.
+    $this->init();
+    return $this;
+  }
+
+}
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
index 093c787..d0eb123 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
@@ -62,10 +62,14 @@ public function __construct(LanguageManager $language_manager, ContextInterface
   public function configContext(ConfigEvent $event) {
     $context = $event->getContext();
 
-    // If there is a user set in the current context, set the language based on
-    // the preferred language of the user. Otherwise set it based on the
-    // negotiated interface language.
-    if ($account = $context->get('user.account')) {
+    // If there is a language set explicitly in current context, use it.
+    // otherwise check if there is a user set in the current context,
+    // to set the language based on the preferred language of the user.
+    // Otherwise set it based on the negotiated interface language.
+    if ($language = $context->get('language')) {
+      $context->set('locale.language', $language);
+    }
+    elseif ($account = $context->get('user.account')) {
       $context->set('locale.language', language_load(user_preferred_langcode($account)));
     }
     elseif ($language = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)) {
