diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml
index 2633fdc..928e767 100644
--- a/core/modules/language/config/schema/language.schema.yml
+++ b/core/modules/language/config/schema/language.schema.yml
@@ -101,6 +101,23 @@ language.entity.*:
       type: boolean
       label: 'Locked'
 
+language.content_settings.*.*:
+  type: config_entity
+  label: 'Content Language Settings'
+  mapping:
+    id:
+      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'
+
 language.settings:
   type: mapping
   label: 'Language settings'
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index a605360..c712ed0 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\ContentBundleLanguageSettings;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUI;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrlFallback;
@@ -196,7 +198,8 @@ 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();
+  \Drupal::config('language.content_settings.' . String::checkPlain($entity_type))->set('entities.'. $bundle,
+      array('langcode' => $values['langcode'], 'language_show' => $values['language_show']))->save();
 }
 
 /**
@@ -213,7 +216,7 @@ 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));
+  $configuration = \Drupal::config('language.content_settings.' . String::checkPlain($entity_type))->get('entities.'. $bundle);
   if (is_null($configuration)) {
     $configuration = array();
   }
@@ -230,28 +233,7 @@ 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';
+  ContentBundleLanguageSettings::deleteByEntityTypeBundle($entity_type, $bundle);
 }
 
 /**
diff --git a/core/modules/language/src/Element/LanguageConfiguration.php b/core/modules/language/src/Element/LanguageConfiguration.php
index 5ae8b00..02a3d03 100644
--- a/core/modules/language/src/Element/LanguageConfiguration.php
+++ b/core/modules/language/src/Element/LanguageConfiguration.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Render\Element\FormElement;
+use Drupal\language\Entity\ContentBundleLanguageSettings;
 
 /**
  * Provides language element configuration.
@@ -40,18 +41,20 @@ public static function processLanguageConfiguration(&$element, FormStateInterfac
     // Avoid validation failure since we are moving the '#options' key in the
     // nested 'language' select element.
     unset($element['#options']);
+    /** @var \Drupal\language\Entity\ContentBundleLanguageSettings $config */
+    $config = $element['#default_value'];
     $element['langcode'] = array(
       '#type' => 'select',
       '#title' => t('Default language'),
       '#options' => $options + static::getDefaultOptions(),
       '#description' => t('Explanation of the language options is found on the <a href="@languages_list_page">languages list page</a>.', array('@languages_list_page' => \Drupal::url('language.admin_overview'))),
-      '#default_value' => isset($element['#default_value']['langcode']) ? $element['#default_value']['langcode'] : NULL,
+      '#default_value' => $config->getDefaultLangcode(),
     );
 
     $element['language_show'] = array(
       '#type' => 'checkbox',
       '#title' => t('Show language selector on create and edit pages'),
-      '#default_value' => isset($element['#default_value']['language_show']) ? $element['#default_value']['language_show'] : NULL,
+      '#default_value' => $config->getLanguageShow(),
     );
 
     // Add the entity type and bundle information to the form if they are set.
diff --git a/core/modules/language/src/Entity/ContentBundleLanguageSettings.php b/core/modules/language/src/Entity/ContentBundleLanguageSettings.php
new file mode 100644
index 0000000..9402ca9
--- /dev/null
+++ b/core/modules/language/src/Entity/ContentBundleLanguageSettings.php
@@ -0,0 +1,141 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Entity\ContentLanguageSettings.
+ */
+
+namespace Drupal\language\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Language\LanguageInterface;
+
+
+/**
+ * Defines the ContentLanguageSettings entity.
+ *
+ * @ConfigEntityType(
+ *   id = "content_language_settings",
+ *   label = @Translation("Content Bundle Language Settings"),
+ *   fieldable = FALSE,
+ *   handlers = {
+ *   },
+ *   admin_permission = "administer languages",
+ *   config_prefix = "content_settings",
+ *   entity_keys = {
+ *     "id" = "entityType",
+ *     "bundle" = "bundle",
+ *   },
+ * )
+ */
+class ContentBundleLanguageSettings extends ConfigEntityBase {
+
+  /**
+   * The entity type (machine name).
+   *
+   * @var string
+   */
+  protected $entityType;
+
+  /**
+   * The bundle (machine name).
+   *
+   * @var string
+   */
+  protected $bundle;
+
+
+  /**
+   * @var string $defaultLangcode
+   */
+  private $defaultLangcode;
+
+  /**
+   * @var boolean $languageShow
+   */
+  private $languageShow;
+
+  public function __construct(array $values, $entity_type = 'content_language_settings') {
+    parent::__construct($values, $entity_type);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function id() {
+    return $this->entityType . '.' . $this->bundle;
+  }
+
+  /**
+   * @param string $default_langcode
+   *
+   * @return $this;
+   */
+  public function setDefaultLangcode($default_langcode) {
+    $this->defaultLangcode = $default_langcode;
+
+    return $this;
+  }
+
+  /**
+   * @return string
+   */
+  public function getDefaultLangcode() {
+    return $this->defaultLangcode;
+  }
+
+  /**
+   * @param boolean $language_show
+   *
+   * @return $this
+   */
+  public function setLanguageShow($language_show) {
+    $this->languageShow = $language_show;
+
+    return $this;
+  }
+
+  /**
+   * @return boolean
+   */
+  public function getLanguageShow() {
+    return $this->languageShow;
+  }
+
+  /**
+   * 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->languageShow || $this->defaultLangcode != 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('content_language_settings')->load($entity_type_id . '.' . $bundle);
+    if ($config == NULL) {
+      $config = new ContentBundleLanguageSettings(['entityType' => $entity_type_id, 'bundle' => $bundle]);
+      $config->setDefaultLangcode(LanguageInterface::LANGCODE_SITE_DEFAULT)
+        ->setLanguageShow(false);
+    }
+    return $config;
+  }
+
+  public static function deleteByEntityTypeBundle($entity_type_id, $bundle) {
+    \Drupal::entityManager()->getStorage('content_language_settings')->load($entity_type_id . '.' . $bundle)->delete();
+  }
+
+}
diff --git a/core/modules/language/src/Form/ContentLanguageSettingsForm.php b/core/modules/language/src/Form/ContentLanguageSettingsForm.php
index a415379..b5ee7ee 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\ContentBundleLanguageSettings;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -76,11 +77,11 @@ 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 = ContentBundleLanguageSettings::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] = $config;
       }
     }
 
@@ -145,16 +146,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 = new ContentBundleLanguageSettings(['entityType'=> $entity_type, 'bundle' => $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);
     }
   }
 
