diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml
index 2633fdc..0b767ea 100644
--- a/core/modules/language/config/schema/language.schema.yml
+++ b/core/modules/language/config/schema/language.schema.yml
@@ -101,34 +101,25 @@ language.entity.*:
       type: boolean
       label: 'Locked'
 
-language.settings:
-  type: mapping
-  label: 'Language settings'
+language.content_settings.*.*:
+  type: config_entity
+  label: 'Content Language Settings'
   mapping:
-    entities:
-      type: sequence
-      label: 'Entity type'
-      sequence:
-        - type: sequence
-          label: 'Bundle'
-          sequence:
-            - type: mapping
-              label: 'Custom language settings'
-              mapping:
-                language:
-                  type: mapping
-                  label: 'Custom language settings'
-                  mapping:
-                    default_configuration:
-                      type: mapping
-                      label: 'Default language'
-                      mapping:
-                        langcode:
-                          type: string
-                          label: 'Default language'
-                        language_show:
-                          type: boolean
-                          label: 'Show language selector on create and edit pages'
+    id:
+      type: string
+      label: 'ID'
+    entity_type:
+      type: string
+      label: 'Entity Type ID'
+    bundle:
+      type:  string
+      label: 'Bundle'
+    default_langcode:
+      type: string
+      label: 'Default language'
+    language_show:
+      type: boolean
+      label: 'Show language selector on create and edit pages'
 
 condition.plugin.language:
   type: condition.plugin
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index a605360..cb37b16 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -5,10 +5,12 @@
  * Add language handling functionality to Drupal.
  */
 
+use Drupal\Component\Utility\String;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
+use Drupal\language\Entity\ContentLanguageSettings;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUI;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrlFallback;
@@ -196,7 +198,14 @@ function language_configuration_element_submit(&$form, FormStateInterface $form_
  *   - language_show: if the language element should be hidden or not.
  */
 function language_save_default_configuration($entity_type, $bundle, $values = array()) {
-  \Drupal::config('language.settings')->set(language_get_default_configuration_settings_key($entity_type, $bundle), array('langcode' => $values['langcode'], 'language_show' => $values['language_show']))->save();
+  $config = ContentLanguageSettings::loadByEntityTypeBundle($entity_type, $bundle);
+  if (isset($values['langcode'])) {
+    $config->setDefaultLangcode(String::checkPlain($values['langcode']));
+  }
+  if (isset($values['language_show'])) {
+    $config->setLanguageShow(String::checkPlain($values['language_show']));
+  }
+  $config->save();
 }
 
 /**
@@ -213,12 +222,8 @@ function language_save_default_configuration($entity_type, $bundle, $values = ar
  *   - language_show: if the language element is hidden or not.
  */
 function language_get_default_configuration($entity_type, $bundle) {
-  $configuration = \Drupal::config('language.settings')->get(language_get_default_configuration_settings_key($entity_type, $bundle));
-  if (is_null($configuration)) {
-    $configuration = array();
-  }
-  $configuration += array('langcode' => LanguageInterface::LANGCODE_SITE_DEFAULT, 'language_show' => FALSE);
-  return $configuration;
+  $config = ContentLanguageSettings::loadByEntityTypeBundle($entity_type, $bundle);
+  return ['langcode' => $config->getDefaultLangcode(), 'language_show' => $config->getLanguageShow()];
 }
 
 /**
@@ -230,28 +235,10 @@ function language_get_default_configuration($entity_type, $bundle) {
  *   A string representing the bundle.
  */
 function language_clear_default_configuration($entity_type, $bundle) {
-  \Drupal::config('language.settings')->clear(language_get_default_configuration_settings_key($entity_type, $bundle))->save();
-}
-
-/**
- * Returns the root name of the variables used to store the configuration.
- *
- * Based on the entity type and bundle, the variables used to store the
- * configuration will have a common root name.
- *
- * @param string $entity_type
- *   A string representing the entity type.
- * @param string $bundle
- *   A string representing the bundle.
- *
- * @return string
- *   The root name of the variables.
- */
-function language_get_default_configuration_settings_key($entity_type, $bundle) {
-  // Replace all the characters that are not letters, numbers or "_" with "_".
-  $entity_type = preg_replace('/[^0-9a-zA-Z_]/', "_", $entity_type);
-  $bundle = preg_replace('/[^0-9a-zA-Z_]/', "_", $bundle);
-  return 'entities.' . $entity_type . '.' . $bundle . '.language.default_configuration';
+  $config = ContentLanguageSettings::loadByEntityTypeBundle($entity_type, $bundle);
+  if (!$config->isNew()) {
+    $config->delete();
+  }
 }
 
 /**
diff --git a/core/modules/language/src/Entity/ContentLanguageSettings.php b/core/modules/language/src/Entity/ContentLanguageSettings.php
new file mode 100644
index 0000000..cbbf268
--- /dev/null
+++ b/core/modules/language/src/Entity/ContentLanguageSettings.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Entity\ContentLanguageSettings.
+ */
+
+namespace Drupal\language\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Language\LanguageInterface;
+
+
+/**
+ * Defines the ContentLanguageSettings entity.
+ *
+ * @ConfigEntityType(
+ *   id = "language_content_settings",
+ *   label = @Translation("Content Language Settings"),
+ *   admin_permission = "administer languages",
+ *   config_prefix = "content_settings",
+ *   entity_keys = {
+ *     "id" = "id",
+ *   },
+ * )
+ */
+class ContentLanguageSettings extends ConfigEntityBase {
+
+  /**
+   * The id. Combination of $entity_type.$bundle.
+   *
+   * @var string
+   */
+  protected $id;
+
+  /**
+   * The entity type (machine name).
+   *
+   * @var string
+   */
+  protected $entity_type;
+
+  /**
+   * The bundle (machine name).
+   *
+   * @var string
+   */
+  protected $bundle;
+
+  /**
+   * The default language code.
+   *
+   * @var string
+   */
+  protected $default_langcode = LanguageInterface::LANGCODE_SITE_DEFAULT;
+
+  /**
+   * Indicates if the language is exposed or not.
+   *
+   * @var bool
+   */
+  protected $language_show = FALSE;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->entity_type . '.' . $this->bundle;
+  }
+
+  /**
+   * Sets the default language code.
+   *
+   * @param string $default_langcode
+   *
+   * @return $this;
+   */
+  public function setDefaultLangcode($default_langcode) {
+    $this->default_langcode = $default_langcode;
+
+    return $this;
+  }
+
+  /**
+   * Gets the default language code.
+   *
+   * @return string
+   */
+  public function getDefaultLangcode() {
+    return $this->default_langcode;
+  }
+
+  /**
+   * Sets if the language must be exposed or not.
+   *
+   * @param bool $language_show
+   *
+   * @return $this
+   */
+  public function setLanguageShow($language_show) {
+    $this->language_show = $language_show;
+
+    return $this;
+  }
+
+  /**
+   * Checks if the language must be exposed or not.
+   *
+   * @return bool
+   */
+  public function getLanguageShow() {
+    return $this->language_show;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\Entity::preSave().
+   *
+   * @throws \Drupal\Core\Field\FieldException
+   *   If the field definition is invalid.
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   In case of failures at the configuration storage level.
+   */
+  public function preSave(EntityStorageInterface $storage) {
+    if ($this->isNew()) {
+      $this->id = $this->id();
+    }
+    parent::preSave($storage);
+  }
+
+  /**
+   * Checks if this config object differs from default values in any property.
+   *
+   * @return bool
+   *   True if any of the properties are the default values. False otherwise.
+   */
+  public function differsFromDefaultConfiguration() {
+    return ($this->language_show || $this->default_langcode != LanguageInterface::LANGCODE_SITE_DEFAULT);
+  }
+
+  /**
+   * Loads a content language config entity based on the entity type and bundle.
+   *
+   * @param string $entity_type_id
+   *   ID of the entity type.
+   * @param string $bundle
+   *   Bundle name.
+   *
+   * @return static
+   *   The content language config entity if one exists. Otherwise, returns
+   *   sensible default values.
+   */
+  public static function loadByEntityTypeBundle($entity_type_id, $bundle) {
+    $config = \Drupal::entityManager()->getStorage('language_content_settings')->load($entity_type_id . '.' . $bundle);
+    if ($config == NULL) {
+      $config = ContentLanguageSettings::create(['entity_type' => $entity_type_id, 'bundle' => $bundle]);
+    }
+    return $config;
+  }
+
+}
diff --git a/core/modules/language/src/Form/ContentLanguageSettingsForm.php b/core/modules/language/src/Form/ContentLanguageSettingsForm.php
index a415379..b780adf 100644
--- a/core/modules/language/src/Form/ContentLanguageSettingsForm.php
+++ b/core/modules/language/src/Form/ContentLanguageSettingsForm.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\language\Entity\ContentLanguageSettings;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -76,11 +77,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
       // Check whether we have any custom setting.
       foreach ($bundles[$entity_type_id] as $bundle => $bundle_info) {
-        $conf = language_get_default_configuration($entity_type_id, $bundle);
-        if (!empty($conf['language_show']) || $conf['langcode'] != LanguageInterface::LANGCODE_SITE_DEFAULT) {
+        $config = ContentLanguageSettings::loadByEntityTypeBundle($entity_type_id, $bundle);
+        if ($config->differsFromDefaultConfiguration()) {
           $default[$entity_type_id] = $entity_type_id;
         }
-        $language_configuration[$entity_type_id][$bundle] = $conf;
+        $language_configuration[$entity_type_id][$bundle]['language_show'] = $config->getLanguageShow();
+        $language_configuration[$entity_type_id][$bundle]['langcode'] = $config->getDefaultLangcode();
       }
     }
 
@@ -145,16 +147,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $config = $this->config('language.settings');
     foreach ($form_state->getValue('settings') as $entity_type => $entity_settings) {
       foreach ($entity_settings as $bundle => $bundle_settings) {
-        $config->set(language_get_default_configuration_settings_key($entity_type, $bundle), array(
-          'langcode' => $bundle_settings['settings']['language']['langcode'],
-          'language_show' => $bundle_settings['settings']['language']['language_show'],
-        ));
+        $config = ContentLanguageSettings::loadByEntityTypeBundle($entity_type, $bundle);
+        $config->setDefaultLangcode($bundle_settings['settings']['language']['langcode'])
+          ->setLanguageShow($bundle_settings['settings']['language']['language_show'])
+          ->save();
       }
     }
-    $config->save();
     drupal_set_message($this->t('Settings successfully updated.'));
   }
 
diff --git a/core/modules/language/src/Tests/LanguageConfigSchemaTest.php b/core/modules/language/src/Tests/LanguageConfigSchemaTest.php
index aeddc2b..66fc831 100644
--- a/core/modules/language/src/Tests/LanguageConfigSchemaTest.php
+++ b/core/modules/language/src/Tests/LanguageConfigSchemaTest.php
@@ -65,11 +65,11 @@ function testValidLanguageConfigSchema() {
 
     $this->drupalPostForm($settings_path, $edit, t('Save configuration'));
 
-    $config_data = \Drupal::config('language.settings')->get();
+    $config_data = \Drupal::config('language.content_settings.menu_link_content.menu_link_content')->get();
     // Make sure configuration saved correctly.
-    $this->assertTrue($config_data['entities']['menu_link_content']['menu_link_content']['language']['default_configuration']['language_show']);
+    $this->assertTrue($config_data['language_show']);
 
-    $this->assertConfigSchema(\Drupal::service('config.typed'), 'language.settings', $config_data);
+    $this->assertConfigSchema(\Drupal::service('config.typed'), 'language.content_settings.menu_link_content.menu_link_content', $config_data);
   }
 
 }
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 36c7d75..f1a645e 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -159,8 +159,7 @@ function node_uninstall() {
   foreach ($types as $config_name) {
     $type = \Drupal::config($config_name)->get('type');
     if (\Drupal::moduleHandler()->moduleExists('language')) {
-      $key = language_get_default_configuration_settings_key('node', $type);
-      \Drupal::config('language.settings')->clear($key)->save();
+      language_clear_default_configuration('node', $type);
     }
   }
 
