diff --git a/core/lib/Drupal/Core/Language/Language.php b/core/lib/Drupal/Core/Language/Language.php
index ec3ce71..7702496 100644
--- a/core/lib/Drupal/Core/Language/Language.php
+++ b/core/lib/Drupal/Core/Language/Language.php
@@ -80,7 +80,9 @@ class Language implements LanguageInterface {
   public function __construct(array $values = array()) {
     // Set all the provided properties for the language.
     foreach ($values as $key => $value) {
-      $this->{$key} = $value;
+      if (property_exists($this, $key)) {
+        $this->{$key} = $value;
+      }
     }
     // If some values were not set, set sane defaults of a predefined language.
     if (!isset($values['name']) || !isset($values['direction'])) {
diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index e0916e4..aac3c65 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -27,11 +27,17 @@ class LanguageManager implements LanguageManagerInterface {
   protected $translation;
 
   /**
-   * An array of all the available languages keyed by language code.
+   * A static cache of translated language lists.
+   *
+   * Array of arrays to cache the result of self::getLanguages() keyed by the
+   * language the list is translated to (first level) and the flags provided to
+   * the method (second level).
    *
    * @var \Drupal\Core\Language\LanguageInterface[]
+   *
+   * @see \Drupal\Core\Language\LanguageManager::getLanguages()
    */
-  protected $languages;
+  protected $languages = array();
 
   /**
    * The default language object.
@@ -130,35 +136,19 @@ public function getDefaultLanguage() {
    * {@inheritdoc}
    */
   public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
-    // Initialize master language list.
-    if (!isset($this->languages)) {
-      // No language module, so use the default language only.
+    $static_cache_id = $this->getCurrentLanguage()->getId();
+    if (!isset($this->languages[$static_cache_id][$flags])) {
+      // If this language manager is used, there are no configured languages.
+      // The default language and locked languages comprise the full language
+      // list.
       $default = $this->getDefaultLanguage();
-      $this->languages = array($default->getId() => $default);
-      // Add the special languages, they will be filtered later if needed.
-      $this->languages += $this->getDefaultLockedLanguages($default->getWeight());
-    }
+      $languages = array($default->getId() => $default);
+      $languages += $this->getDefaultLockedLanguages($default->getWeight());
 
-    // Filter the full list of languages based on the value of the $all flag. By
-    // default we remove the locked languages, but the caller may request for
-    // those languages to be added as well.
-    $filtered_languages = array();
-
-    // Add the site's default language if flagged as allowed value.
-    if ($flags & LanguageInterface::STATE_SITE_DEFAULT) {
-      // Setup a language to have the defaults, but with overridden name.
-      $default = $this->getDefaultLanguage();
-      $default->setName($this->t("Site's default language (@lang_name)", array('@lang_name' => $default->getName())));
-      $filtered_languages[LanguageInterface::LANGCODE_SITE_DEFAULT] = $default;
+      // Filter the full list of languages based on the value of $flags.
+      $this->languages[$static_cache_id][$flags] = $this->filterLanguages($languages, $flags);
     }
-
-    foreach ($this->languages as $id => $language) {
-      if (($language->isLocked() && ($flags & LanguageInterface::STATE_LOCKED)) || (!$language->isLocked() && ($flags & LanguageInterface::STATE_CONFIGURABLE))) {
-        $filtered_languages[$id] = $language;
-      }
-    }
-
-    return $filtered_languages;
+    return $this->languages[$static_cache_id][$flags];
   }
 
   /**
@@ -382,4 +372,44 @@ public function getConfigOverrideLanguage() {
     return $this->getCurrentLanguage();
   }
 
+
+  /**
+   * Filters the full list of languages based on the value of the flag.
+   *
+   * The locked languages are removed by default.
+   *
+   * @param \Drupal\Core\Language\LanguageInterface[] $languages
+   *    Array with languages to be filtered.
+   * @param int $flags
+   *   (optional) Specifies the state of the languages that have to be returned.
+   *   It can be: LanguageInterface::STATE_CONFIGURABLE,
+   *   LanguageInterface::STATE_LOCKED, or LanguageInterface::STATE_ALL.
+   *
+   * @return \Drupal\Core\Language\LanguageInterface[]
+   *   An associative array of languages, keyed by the language code.
+   */
+  protected function filterLanguages(array $languages, $flags = LanguageInterface::STATE_CONFIGURABLE) {
+    // STATE_ALL means we don't actually filter, so skip the rest of the method.
+    if ($flags == LanguageInterface::STATE_ALL) {
+      return $languages;
+    }
+
+    $filtered_languages = array();
+    // Add the site's default language if requested.
+    if ($flags & LanguageInterface::STATE_SITE_DEFAULT) {
+      // Setup a language to have the defaults, but with overridden name.
+      $default = $this->getDefaultLanguage();
+      $default->setName($this->t("Site's default language (@lang_name)", array('@lang_name' => $default->getName())));
+      $filtered_languages[LanguageInterface::LANGCODE_SITE_DEFAULT] = $default;
+    }
+
+    foreach ($languages as $id => $language) {
+      if (($language->isLocked() && ($flags & LanguageInterface::STATE_LOCKED)) || (!$language->isLocked() && ($flags & LanguageInterface::STATE_CONFIGURABLE))) {
+        $filtered_languages[$id] = $language;
+      }
+    }
+
+    return $filtered_languages;
+  }
+
 }
diff --git a/core/modules/language/src/ConfigurableLanguageManager.php b/core/modules/language/src/ConfigurableLanguageManager.php
index 534f232..32429e5 100644
--- a/core/modules/language/src/ConfigurableLanguageManager.php
+++ b/core/modules/language/src/ConfigurableLanguageManager.php
@@ -17,7 +17,6 @@
 use Drupal\Core\Url;
 use Drupal\language\Config\LanguageConfigFactoryOverrideInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
-use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
@@ -247,7 +246,7 @@ public function reset($type = NULL) {
       $this->negotiatedMethods = array();
       $this->languageTypes = NULL;
       $this->languageTypesInfo = NULL;
-      $this->languages = NULL;
+      $this->languages = array();
       if ($this->negotiator) {
         $this->negotiator->reset();
       }
@@ -279,37 +278,45 @@ public function setNegotiator(LanguageNegotiatorInterface $negotiator) {
    * {@inheritdoc}
    */
   public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
-    if (!isset($this->languages)) {
-      // Prepopulate the language list with the default language to keep things
-      // working even if we have no configuration.
-      $default = $this->getDefaultLanguage();
-      $this->languages = array($default->getId() => $default);
-
-      // Retrieve the list of languages defined in configuration.
-      $prefix = 'language.entity.';
-      $config_ids = $this->configFactory->listAll($prefix);
+    // If a config override is set, cache using that language's ID.
+    if ($override_language = $this->getConfigOverrideLanguage()) {
+      $static_cache_id = $override_language->getId();
+    }
+    else {
+      $static_cache_id = $this->getCurrentLanguage()->getId();
+    }
 
-      // Instantiate languages from config objects.
-      $weight = 0;
+    if (!isset($this->languages[$static_cache_id][$flags])) {
+      // Initialize the language list with the default language and default
+      // locked languages. These cannot be removed. This serves as a fallback
+      // list if this method is invoked while the language module is installed
+      // and the configuration entities for languages are not yet fully imported.
+      $default = $this->getDefaultLanguage();
+      $languages = array($default->getId() => $default);
+      $languages += $this->getDefaultLockedLanguages($default->getWeight());
+
+      // Load configurable languages on top of the defaults. Ideally this could
+      // use the entity API to load and instantiate ConfigurableLanguage objects.
+      // However the entity API depends on the language system, so that would
+      // result in infinite loops. We use the configuration system directly and
+      // instantiate runtime Language objects. When language entities are imported
+      // those cover the default and locked languages, so site-specific
+      // configuration will prevail over the fallback values. Having them in the
+      // array already ensures if this is invoked in the middle of importing
+      // language configuration entities, the defaults are always present.
+      $config_ids = $this->configFactory->listAll('language.entity.');
       foreach ($this->configFactory->loadMultiple($config_ids) as $config) {
         $data = $config->get();
-        $langcode = $data['id'];
-        // Initialize default property so callers have an easy reference and can
-        // save the same object without data loss.
-        $data['default'] = ($langcode == $default->getId());
         $data['name'] = $data['label'];
-        $this->languages[$langcode] = new Language($data);
-        $weight = max(array($weight, $this->languages[$langcode]->getWeight()));
+        $languages[$data['id']] = new Language($data);
       }
+      Language::sort($languages);
 
-      // Add locked languages, they will be filtered later if needed.
-      $this->languages += $this->getDefaultLockedLanguages($weight);
-
-      // Sort the language list by weight then title.
-      Language::sort($this->languages);
+      // Filter the full list of languages based on the value of $flags.
+      $this->languages[$static_cache_id][$flags] = $this->filterLanguages($languages, $flags);
     }
 
-    return parent::getLanguages($flags);
+    return $this->languages[$static_cache_id][$flags];
   }
 
   /**
diff --git a/core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php b/core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php
new file mode 100644
index 0000000..15290fd
--- /dev/null
+++ b/core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Tests\LanguageSelectorTranslatableTest.
+ */
+
+namespace Drupal\language\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests the content translation settings language selector options.
+ *
+ * @group language
+ */
+class LanguageSelectorTranslatableTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array(
+    'language',
+    'content_translation',
+    'node',
+    'comment',
+    'field_ui',
+    'entity_test',
+    'locale',
+  );
+
+  /**
+   * The user with administrator privileges.
+   *
+   * @var \Drupal\user\Entity\User;
+   */
+  public $administrator;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create user and set permissions.
+    $this->administrator = $this->drupalCreateUser($this->getAdministratorPermissions(), 'administrator');
+    $this->drupalLogin($this->administrator);
+  }
+
+  /**
+   * Returns an array of permissions needed for the translator.
+   */
+  protected function getAdministratorPermissions() {
+    return array_filter(
+      array('translate interface',
+        'administer content translation',
+        'create content translations',
+        'update content translations',
+        'delete content translations',
+        'administer languages',
+      )
+    );
+  }
+
+  /**
+   * Tests content translation language selectors are correctly translated.
+   */
+  public function testLanguageStringSelector() {
+    // Add another language.
+    $edit = array('predefined_langcode' => 'es');
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
+
+    // Translate the string English in Spanish (Inglés). Override config entity.
+    $name_translation = 'Inglés';
+    \Drupal::languageManager()
+      ->getLanguageConfigOverride('es', 'language.entity.en')
+      ->set('label', $name_translation)
+      ->save();
+
+    // Check content translation overview selector.
+    $path = 'es/admin/config/regional/content-language';
+    $this->drupalGet($path);
+
+    // Get en language from selector.
+    $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => 'edit-settings-node-node-settings-language-langcode', ':option' => 'en'));
+
+    // Check that the language text is translated.
+    $this->assertEqual((string) $elements[0], $name_translation, 'Checking the option string English is translated to Spanish.');
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Language/LanguageUnitTest.php b/core/tests/Drupal/Tests/Core/Language/LanguageUnitTest.php
index e21ab6f..49a9dbf 100644
--- a/core/tests/Drupal/Tests/Core/Language/LanguageUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Language/LanguageUnitTest.php
@@ -18,6 +18,20 @@
 class LanguageUnitTest extends UnitTestCase {
 
   /**
+   * @covers ::__construct
+   */
+  public function testConstruct() {
+    $name = $this->randomMachineName();
+    $language_code = $this->randomMachineName(2);
+    $uuid = $this->randomMachineName();
+    $language = new Language(array('id' => $language_code, 'name' => $name, 'uuid' => $uuid));
+    // Test that nonexistent properties are not added to the language object.
+    $this->assertTrue(property_exists($language, 'id'));
+    $this->assertTrue(property_exists($language, 'name'));
+    $this->assertFalse(property_exists($language, 'uuid'));
+  }
+
+  /**
    * @covers ::getName()
    * @covers ::setName()
    */
