diff --git a/core/lib/Drupal/Core/Cache/RuntimeCacheableDependencyInterface.php b/core/lib/Drupal/Core/Cache/RuntimeCacheableDependencyInterface.php
new file mode 100644
index 0000000..03d88d4
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/RuntimeCacheableDependencyInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Cache\RuntimeCacheableDependencyInterface.
+ */
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Interface for objects that can change cache dependencies during runtime.
+ *
+ * @ingroup cache
+ */
+interface RuntimeCacheableDependencyInterface {
+
+  /**
+   * Adds cache contexts during runtime.
+   *
+   * @param string[] $cache_contexts
+   *   An array of cache context tokens to add.
+   */
+  public function addRuntimeCacheContexts(array $cache_contexts);
+
+  /**
+   * Adds cache tags during runtime.
+   *
+   * @param string[] $cache_tags
+   *   An array of cache tags to add.
+   */
+  public function addRuntimeCacheTags(array $cache_tags);
+
+  /**
+   * Sets the cache max age during runtime.
+   *
+   * @param int $max_age
+   *   The cache max-age value.
+   */
+  public function setRuntimeCacheMaxAge($max_age);
+
+}
diff --git a/core/lib/Drupal/Core/Config/ConfigBase.php b/core/lib/Drupal/Core/Config/ConfigBase.php
index eee76a2..556926d 100644
--- a/core/lib/Drupal/Core/Config/ConfigBase.php
+++ b/core/lib/Drupal/Core/Config/ConfigBase.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheableDependencyInterface;
+use Drupal\Core\Cache\RuntimeCacheableDependencyInterface;
 use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
 
 /**
@@ -28,7 +29,7 @@
  * @see \Drupal\Core\Config\Config
  * @see \Drupal\Core\Theme\ThemeSettings
  */
-abstract class ConfigBase implements CacheableDependencyInterface {
+abstract class ConfigBase implements CacheableDependencyInterface, RuntimeCacheableDependencyInterface {
   use DependencySerializationTrait;
 
   /**
@@ -46,6 +47,27 @@
   protected $data = array();
 
   /**
+   * The cache contexts this configuration object provides.
+   *
+   * @var string[]
+   */
+  protected $cacheContexts = [];
+
+  /**
+   * The cache tags this configuration object provides.
+   *
+   * @var string[]
+   */
+  protected $cacheTags = [];
+
+  /**
+   * The cache max age this configuration object provides.
+   *
+   * @var int
+   */
+  protected $cacheMaxAge;
+
+  /**
    * The maximum length of a configuration object name.
    *
    * Many filesystems (including HFS, NTFS, and ext4) have a maximum file name
@@ -269,7 +291,7 @@ public function merge(array $data_to_merge) {
    * {@inheritdoc}
    */
   public function getCacheContexts() {
-    return [];
+    return $this->cacheContexts;
   }
 
   /**
@@ -286,4 +308,25 @@ public function getCacheMaxAge() {
     return Cache::PERMANENT;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function addRuntimeCacheContexts(array $cache_contexts) {
+    $this->cacheContexts = Cache::mergeContexts($this->cacheContexts, $cache_contexts);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addRuntimeCacheTags(array $cache_tags) {
+    $this->cacheTags = Cache::mergeTags($this->cacheTags, $cache_tags);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRuntimeCacheMaxAge($max_age) {
+    $this->cacheMaxAge = Cache::mergeMaxAges($this->cacheMaxAge, $max_age);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index cdfd951..61328a2 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -9,6 +9,8 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\Context\CacheContextInterface;
+use Drupal\Core\Cache\RuntimeCacheableDependencyInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
@@ -126,6 +128,10 @@ protected function doGet($name, $immutable = TRUE) {
           $this->cache[$cache_key]->setSettingsOverride($GLOBALS['config'][$name]);
         }
       }
+
+      // Propagate cache contexts to the config object.
+      $this->propagateCacheableDependencyOverrides($cache_key);
+
       return $this->cache[$cache_key];
     }
   }
@@ -183,6 +189,10 @@ protected function doLoadMultiple(array $names, $immutable = TRUE) {
             $this->cache[$cache_key]->setSettingsOverride($GLOBALS['config'][$name]);
           }
         }
+
+        // Propagate cacheable dependencies to the config object.
+        $this->propagateCacheableDependencyOverrides($cache_key);
+
         $list[$name] = $this->cache[$cache_key];
       }
     }
@@ -210,6 +220,24 @@ protected function loadOverrides(array $names) {
   }
 
   /**
+   * Propagates overridden cacheable dependencies to cached config objects.
+   *
+   * @param string $cache_key
+   *   The key of the cached config object to update.
+   */
+  protected function propagateCacheableDependencyOverrides($cache_key) {
+    $overrides = ['contexts' => [], 'tags' => [], 'max_age' => Cache::PERMANENT];
+    foreach ($this->configFactoryOverrides as $override) {
+      $overrides['contexts'] = Cache::mergeContexts($overrides['contexts'], $override->getCacheContexts());
+      $overrides['tags'] = Cache::mergeTags($overrides['tags'], $override->getCacheTags());
+      $overrides['max_age'] = Cache::mergeMaxAges($overrides['max_age'], $override->getCacheMaxAge());
+    }
+    $this->cache[$cache_key]->addRuntimeCacheContexts($overrides['contexts']);
+    $this->cache[$cache_key]->addRuntimeCacheTags($overrides['tags']);
+    $this->cache[$cache_key]->setRuntimeCacheMaxAge($overrides['max_age']);
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function reset($name = NULL) {
diff --git a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php
index 56dbc19..7b07c1a 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactoryOverrideInterface.php
@@ -7,10 +7,12 @@
 
 namespace Drupal\Core\Config;
 
+use Drupal\Core\Cache\CacheableDependencyInterface;
+
 /**
  * Defines the interface for a configuration factory override object.
  */
-interface ConfigFactoryOverrideInterface {
+interface ConfigFactoryOverrideInterface extends CacheableDependencyInterface {
 
   /**
    * Returns config overrides.
diff --git a/core/modules/config/src/Tests/CacheContextConfigOverrideTest.php b/core/modules/config/src/Tests/CacheContextConfigOverrideTest.php
new file mode 100644
index 0000000..00ce58b
--- /dev/null
+++ b/core/modules/config/src/Tests/CacheContextConfigOverrideTest.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config\Tests\CacheContextConfigOverrideTest.
+ */
+
+namespace Drupal\config\Tests;
+
+use Drupal\simpletest\KernelTestBase;
+
+/**
+ * Tests configuration overrides that set cache contexts.
+ *
+ * @group config
+ */
+class CacheContextConfigOverrideTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('system', 'config', 'config_override_test');
+
+  public function testConfigOverride() {
+    // It's pirate day today!
+    $GLOBALS['arr_me_mateys'] = TRUE;
+
+    $config_factory = $this->container->get('config.factory');
+    $config = $config_factory->get('system.theme');
+    $theme = $config->get('default');
+
+    $this->assertEqual('pirate', $theme);
+
+    $this->assertEquals(['pirate_day'], $config->getCacheContexts);
+  }
+
+}
diff --git a/core/modules/config/tests/config_entity_static_cache_test/src/ConfigOverrider.php b/core/modules/config/tests/config_entity_static_cache_test/src/ConfigOverrider.php
index 2867c7d..8dad5bb 100644
--- a/core/modules/config/tests/config_entity_static_cache_test/src/ConfigOverrider.php
+++ b/core/modules/config/tests/config_entity_static_cache_test/src/ConfigOverrider.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config_entity_static_cache_test;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigFactoryOverrideInterface;
 use Drupal\Core\Config\StorageInterface;
 
@@ -40,4 +41,25 @@ public function createConfigObject($name, $collection = StorageInterface::DEFAUL
     return NULL;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return Cache::PERMANENT;
+  }
+
 }
diff --git a/core/modules/config/tests/config_override_test/config_override_test.services.yml b/core/modules/config/tests/config_override_test/config_override_test.services.yml
index c3fae64..88f3550 100644
--- a/core/modules/config/tests/config_override_test/config_override_test.services.yml
+++ b/core/modules/config/tests/config_override_test/config_override_test.services.yml
@@ -7,3 +7,7 @@ services:
     class: Drupal\config_override_test\ConfigOverriderLowPriority
     tags:
       - { name: config.factory.override, priority: -100 }
+  config_override_test.pirate_day_cache_context_overrider:
+    class: Drupal\config_override_test\PirateDayCacheContextConfigOverride
+    tags:
+      - { name: config.factory.override }
diff --git a/core/modules/config/tests/config_override_test/src/ConfigOverrider.php b/core/modules/config/tests/config_override_test/src/ConfigOverrider.php
index 8eb3836..b985782 100644
--- a/core/modules/config/tests/config_override_test/src/ConfigOverrider.php
+++ b/core/modules/config/tests/config_override_test/src/ConfigOverrider.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config_override_test;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigFactoryOverrideInterface;
 
 /**
@@ -44,5 +45,26 @@ public function createConfigObject($name, $collection = StorageInterface::DEFAUL
     return NULL;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return Cache::PERMANENT;
+  }
+
 }
 
diff --git a/core/modules/config/tests/config_override_test/src/ConfigOverriderLowPriority.php b/core/modules/config/tests/config_override_test/src/ConfigOverriderLowPriority.php
index 6b11e0a..1d6f073 100644
--- a/core/modules/config/tests/config_override_test/src/ConfigOverriderLowPriority.php
+++ b/core/modules/config/tests/config_override_test/src/ConfigOverriderLowPriority.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config_override_test;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigFactoryOverrideInterface;
 use Drupal\Core\Config\StorageInterface;
 
@@ -49,5 +50,25 @@ public function createConfigObject($name, $collection = StorageInterface::DEFAUL
     return NULL;
   }
 
-}
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return Cache::PERMANENT;
+  }
 
+}
diff --git a/core/modules/config/tests/config_override_test/src/PirateDayCacheContextConfigOverride.php b/core/modules/config/tests/config_override_test/src/PirateDayCacheContextConfigOverride.php
new file mode 100644
index 0000000..47f7581
--- /dev/null
+++ b/core/modules/config/tests/config_override_test/src/PirateDayCacheContextConfigOverride.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_override_test\PirateDayCacheContextConfigOverride.
+ */
+
+namespace Drupal\config_override_test;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Config\ConfigFactoryOverrideInterface;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Test implementation of a cache context providing config override.
+ */
+class PirateDayCacheContextConfigOverride implements ConfigFactoryOverrideInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function loadOverrides($names) {
+    $overrides = array();
+
+    $it_is_pirate_day = $GLOBALS['arr_me_mateys'];
+    if (in_array('system.theme', $names) && $it_is_pirate_day) {
+      $overrides = $overrides + ['system.theme' => ['default' => 'pirate']];
+    }
+
+    return $overrides;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheSuffix() {
+    return 'PirateDayConfigOverrider';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return ['pirate_day'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    // @todo This is here because we now implement CacheableDependencyInterface,
+    //   but this is not used.
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    // @todo This is here because we now implement CacheableDependencyInterface,
+    //   but this is not used.
+    return Cache::PERMANENT;
+  }
+
+}
diff --git a/core/modules/language/src/Config/LanguageConfigFactoryOverride.php b/core/modules/language/src/Config/LanguageConfigFactoryOverride.php
index 3d0a67b..e2e8c3b 100644
--- a/core/modules/language/src/Config/LanguageConfigFactoryOverride.php
+++ b/core/modules/language/src/Config/LanguageConfigFactoryOverride.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\language\Config;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\ConfigCollectionInfo;
 use Drupal\Core\Config\ConfigCrudEvent;
 use Drupal\Core\Config\ConfigFactoryOverrideBase;
@@ -222,4 +223,25 @@ public function onConfigDelete(ConfigCrudEvent $event) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    return ['languages:language_interface'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    return Cache::PERMANENT;
+  }
+
 }
