diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 4fe105e..be36bc6 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1157,20 +1157,26 @@ function comment_form_node_type_form_alter(&$form, $form_state) {
     );
     // @todo Remove this check once language settings are generalized.
     if (module_exists('translation_entity')) {
-      $form['comment'] += translation_entity_enable_widget($form_state, 'comment_comment_node', $form['#node_type']->type, FALSE);
-      array_unshift($form['#submit'], 'comment_translation_entity_enable_submit');
+      $comment_form_state['translation_entity']['key'] = 'language_configuration';
+      $form['comment'] += translation_entity_enable_widget('comment', 'comment_node_' . $form['#node_type']->type, $comment_form, $comment_form_state);
+      array_unshift($form['#submit'], 'comment_translation_configuration_element_submit');
     }
   }
 }
 
 /**
- * Checks if translation can be enabled.
+ * Comment translation settings submit handler.
+ *
+ * The comment settings form is embedded
  */
-function comment_translation_entity_enable_submit($form, &$form_state) {
-  $comment_form_state = $form_state;
-  $comment_form_state['translation_entity']['variable_name'] = 'translation_entity_enabled_comment_comment_node_' . $form['#node_type']->type;
-  $comment_form_state['translation_entity']['element_name'] = 'translation_entity_enabled_comment_comment_node';
-  translation_entity_enable_widget_submit($form, $comment_form_state);
+function comment_translation_configuration_element_submit($form, &$form_state) {
+  $key = 'language_configuration';
+  $comment_form_state = array(
+    'translation_entity' => array('key' => $key),
+    'language' => array($key => array('entity_type' => 'comment', 'bundle' => 'comment_node_' . $form['#node_type']->type)),
+    'values' => array($key => array('translation_entity' => $form_state['values']['translation_entity'])),
+  );
+  translation_entity_language_configuration_element_submit($form, $comment_form_state);
 }
 
 /**
diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc
index 45d133d..5cd92a4 100644
--- a/core/modules/node/content_types.inc
+++ b/core/modules/node/content_types.inc
@@ -224,14 +224,6 @@ function node_type_form($form, &$form_state, $type = NULL) {
       '#default_value' => $language_configuration,
     );
 
-    // @todo Remove this check once language settings are generalized.
-    if (module_exists('translation_entity')) {
-      $widget = translation_entity_enable_widget($form_state, 'node', $form['#node_type']->type, FALSE);
-      $widget['#element_validate'][] = 'node_type_translation_entity_enable_widget_validate';
-      $form['#submit'][] = 'translation_entity_enable_widget_submit';
-      $form['language'] += $widget;
-    }
-
     $form['#submit'][] = 'language_configuration_element_submit';
   }
   $form['display'] = array(
@@ -294,21 +286,6 @@ function node_type_form($form, &$form_state, $type = NULL) {
 }
 
 /**
- * Checks if translation can be enabled.
- *
- * If language is set to one of the special languages and language selector is
- * not hidden, translation cannot be enabled.
- */
-function node_type_translation_entity_enable_widget_validate($element, &$form_state, $form) {
-  if (language_is_locked($form_state['values']['node_type_language_default']) && $form_state['values']['node_type_language_hidden'] && $form_state['values']['translation_entity_enabled_node']) {
-    foreach (language_list(LANGUAGE_LOCKED) as $language) {
-      $locked_languages[] = $language->name;
-    }
-    form_set_error('node_type_language_translation_entity_enabled', t('Translation is not supported if language is always one of: @locked_languages', array('@locked_languages' => implode(", ", $locked_languages))));
-  }
-}
-
-/**
  * Helper function for teaser length choices.
  *
  * @param int $length
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
index 0adab0c..59579a4 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
@@ -63,10 +63,10 @@ public function form(array $form, array &$form_state, EntityInterface $vocabular
       $form['default_terms_language']['default_language'] = array(
         '#type' => 'language_configuration',
         '#entity_information' => array(
-          'entity_type' => 'vocabulary',
+          'entity_type' => 'taxonomy_term',
           'bundle' => $vocabulary->machine_name,
         ),
-        '#default_value' => language_get_default_configuration('vocabulary', $vocabulary->machine_name),
+        '#default_value' => language_get_default_configuration('taxonomy_term', $vocabulary->machine_name),
       );
     }
     // Set the hierarchy to "multiple parents" by default. This simplifies the
@@ -80,11 +80,6 @@ public function form(array $form, array &$form_state, EntityInterface $vocabular
       $form['vid'] = array('#type' => 'value', '#value' => $vocabulary->vid);
     }
 
-    // @todo Remove this check once language settings are generalized.
-    if (module_exists('translation_entity')) {
-      $form += translation_entity_enable_widget($form_state, 'taxonomy_term', $vocabulary->machine_name);
-    }
-
     return parent::form($form, $form_state, $vocabulary);
   }
 
@@ -102,9 +97,8 @@ protected function actions(array $form, array &$form_state) {
         array_unshift($actions['submit']['#submit'],'language_configuration_element_submit');
         array_unshift($actions['submit']['#submit'], array($this, 'languageConfigurationSubmit'));
       }
-      // @todo Remove this check once language settings are generalized.
       if (module_exists('translation_entity')) {
-        array_unshift($actions['submit']['#submit'], 'translation_entity_enable_widget_submit');
+        array_unshift($actions['submit']['#submit'], 'translation_entity_language_configuration_element_submit');
       }
       return $actions;
     }
diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
index 1bec14f..51c9e64 100644
--- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
+++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php
@@ -55,7 +55,7 @@ function setUp() {
 
     // Enable translation for the entity_test entity type and ensure the change
     // is picked up.
-    variable_set('translation_entity_enabled_entity_test_entity_test', TRUE);
+    translation_entity_set_settings('entity_test', 'entity_test', 'enabled', TRUE);
     drupal_static_reset();
     entity_info_cache_clear();
     menu_router_rebuild();
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index 505e84f..5a9c0ab 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -191,20 +191,89 @@ function translation_entity_add_access(EntityInterface $entity, Language $source
 }
 
 /**
- * Helper function. Determines whether the given entity type is translatable.
+ * Returns the key name used to store the configuration item.
+ *
+ * Based on the entity type and bundle, the variables used to store the
+ * configuration will have a common root name.
+ *
+ * @param string $entity_type
+ *   The type of the entity the setting refer to.
+ * @param string $bundle
+ *   The bundle of the entity the setting refer to.
+ * @param string $setting
+ *   The name of the setting.
+ *
+ * @return string
+ *   The key name of the configuration item.
+ *
+ * @todo Generalize this logic so that it is available to any module needing
+ *   per-bundle configuration.
+ */
+function translation_entity_get_setting_key($entity_type, $bundle, $setting) {
+  $entity_type = preg_replace('/[^0-9a-zA-Z_]/', "_", $entity_type);
+  $bundle = preg_replace('/[^0-9a-zA-Z_]/', "_", $bundle);
+  return $entity_type . '.' . $bundle . '.translation_entity.' . $setting;
+}
+
+/**
+ * Retrieves the value for the specified setting.
+ *
+ * @param string $entity_type
+ *   The type of the entity the setting refer to.
+ * @param string $bundle
+ *   The bundle of the entity the setting refer to.
+ * @param string $setting
+ *   The name of the setting.
+ *
+ * @returns mixed
+ *   The stored value for the given setting.
+ */
+function translation_entity_get_setting($entity_type, $bundle, $setting) {
+  $key = translation_entity_get_setting_key($entity_type, $bundle, $setting);
+  return config('translation_entity.settings')->get($key);
+}
+
+/**
+ * Stores the given value for the specified setting.
+ *
+ * @param string $entity_type
+ *   The type of the entity the setting refer to.
+ * @param string $bundle
+ *   The bundle of the entity the setting refer to.
+ * @param string $setting
+ *   The name of the setting.
+ * @param $value
+ *   The value to be stored for the given setting.
+ */
+function translation_entity_set_setting($entity_type, $bundle, $setting, $value) {
+  $key = translation_entity_get_setting_key($entity_type, $bundle, $setting);
+  return config('translation_entity.settings')->set($key, $value)->save();
+}
+
+/**
+ * Determines whether the given entity type is translatable.
+ *
+ * @param string $entity_type
+ *   The type of the entity.
+ * @param string $bundle
+ *   (optional) The bundle of the entity. If no bundle is provided, all the
+ *   available bundles are checked.
+ * @param boolean $skip_handler
+ *   (optional) Specifies whether the availablity of a field translation handler
+ *   should affect the returned value. By default the check is performed.
+ *
+ * @returns
+ *   TRUE if the specified bundle is translatable. If no bundle is provided
+ *   returns TRUE if at least one of the entity bundles is translatable.
  */
 function translation_entity_enabled($entity_type, $bundle = NULL, $skip_handler = FALSE) {
   $enabled = FALSE;
+  $bundles = !empty($bundle) ? array($bundle) : entity_get_bundles($entity_type);
 
-  if (!empty($bundle)) {
-    $enabled = variable_get("translation_entity_enabled_{$entity_type}_{$bundle}");
-  }
-  else {
-    foreach (entity_get_bundles($entity_type) as $bundle) {
-      if (variable_get("translation_entity_enabled_{$entity_type}_{$bundle}")) {
-        $enabled = TRUE;
-        break;
-      }
+  foreach ($bundles as $bundle) {
+    if (translation_entity_get_setting($entity_type, $bundle, 'enabled')) {
+      $enabled = TRUE;
+      break;
     }
   }
 
@@ -442,62 +511,82 @@ function translation_entity_form_field_ui_field_edit_form_alter(&$form, &$form_s
 }
 
 /**
+ * Implements hook_element_info_alter().
+ */
+function translation_entity_element_info_alter(&$type) {
+  if (isset($type['language_configuration'])) {
+    $type['language_configuration']['#process'][] = 'translation_entity_language_configuration_element_process';
+  }
+}
+/**
  * Returns a widget to enable entity translation per entity bundle.
  *
- * The suffix and bundle parameter are supposed to be provided in a way that the
- * resulting variable name is always in the following form:
- * 'translation_entity_enabled_ENTITY_TYPE_BUNDLE'.
+ * Backward compatibility layer to support entities not using the language
+ * configuration form element.
  *
- * @param string $suffix
- *   An element name suffix, usually the entity type such as 'node' or 'user'.
- * @param $bundle
- *   The bundle name.
- * @param boolean $append_bundle
- *   (optional) If FALSE the bundle name is not appended to variable name.
- *   For instance node_type_form() automatically saves the form values with the
- *   bundle name associated.
- *
- * @return array
- *   The widget to enable the translation
+ * @todo Remove once all core entities have language configuration.
  */
-function translation_entity_enable_widget(&$form_state, $suffix, $bundle, $append_bundle = TRUE) {
-  $element_name = 'translation_entity_enabled_' . $suffix;
-  $variable_name = $element_name . '_' . $bundle;
-  if ($append_bundle) {
-    $element_name .= '_' . $bundle;
+function translation_entity_enable_widget($entity_type, $bundle, &$form, &$form_state) {
+  $key = $form_state['translation_entity']['key'];
+  if (!isset($form_state['language'][$key])) {
+    $form_state['language'][$key] = array();
   }
+  $form_state['language'][$key] += array('entity_type' => $entity_type, 'bundle' => $bundle);
+  $element = translation_entity_language_configuration_element_process(array('#name' => $key), $form_state, $form);
+  unset($element['translation_entity']['#element_validate']);
+  return $element;
+}
 
-  $form_state['translation_entity']['element_name'] = $element_name;
-  $form_state['translation_entity']['variable_name'] = $variable_name;
-
-  return array(
-    $element_name => array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable translation'),
-      '#default_value' => variable_get($variable_name, FALSE),
-      '#element_validate' => array('translation_entity_enable_widget_validate'),
-      '#prefix' => '<label>' . t('Translation') . '</label>',
-    ),
+/**
+ * Process handler for the language_configuration form element.
+ */
+function translation_entity_language_configuration_element_process($element, &$form_state, &$form) {
+  $form_state['translation_entity']['key'] = $element['#name'];
+  $context = $form_state['language'][$element['#name']];
+
+  $element['translation_entity'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable translation'),
+    '#default_value' => translation_entity_enabled($context['entity_type'], $context['bundle']),
+    '#element_validate' => array('translation_entity_language_configuration_element_validate'),
+    '#prefix' => '<label>' . t('Translation') . '</label>',
   );
+
+  $form['#submit'][] = 'translation_entity_language_configuration_element_submit';
+
+  return $element;
 }
 
 /**
  * Checks if translation can be enabled.
+ *
+ * If language is set to one of the special languages and language selector is
+ * not hidden, translation cannot be enabled.
  */
-function translation_entity_enable_widget_validate($element, &$form_state, $form) {
-  // @todo Add common widget validation when entity language settings will be
-  // generalizated. See node_type_translation_entity_enable_widget_validate().
+function translation_entity_language_configuration_element_validate($element, &$form_state, $form) {
+  $key = $form_state['translation_entity']['key'];
+  $values = $form_state['values'][$key];
+  if (language_is_locked($values['langcode']) && $values['language_hidden'] && $values['translation_entity']) {
+    foreach (language_list(LANGUAGE_LOCKED) as $language) {
+      $locked_languages[] = $language->name;
+    }
+    // @todo Set the correct form element name as soon as the element parents
+    //   are correctly set. We should be using NestedArray::getValue() but for
+    //   now we cannot.
+    form_set_error('', t('Translation is not supported if language is always one of: @locked_languages', array('@locked_languages' => implode(', ', $locked_languages))));
+  }
 }
 
 /**
- * Checks if translation can be enabled.
+ * Stores the entity translation settings.
  */
-function translation_entity_enable_widget_submit($form, &$form_state) {
-  $variable_name = $form_state['translation_entity']['variable_name'];
-  $enabled = $form_state['values'][$form_state['translation_entity']['element_name']];
-  // @todo Convert this to CMI once language settings are generalized.
-  if (variable_get($variable_name) != $enabled) {
-    variable_set($variable_name, $enabled);
+function translation_entity_language_configuration_element_submit($form, &$form_state) {
+  $key = $form_state['translation_entity']['key'];
+  $context = $form_state['language'][$key];
+  $enabled = $form_state['values'][$key]['translation_entity'];
+
+  if (translation_entity_enabled($context['entity_type'], $context['bundle']) != $enabled) {
+    translation_entity_set_setting($context['entity_type'], $context['bundle'], 'enabled', $enabled);
     entity_info_cache_clear();
     menu_router_rebuild();
   }
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 565bc7b..df163cd 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -312,10 +312,10 @@ function user_admin_settings($form, &$form_state) {
     $form['language'] = array(
       '#type' => 'fieldset',
       '#title' => t('Language settings'),
+      '#tree' => TRUE,
     );
-
-    $form['language'] += translation_entity_enable_widget($form_state, 'user', 'user');
-    $form['#submit'][] = 'translation_entity_enable_widget_submit';
+    $form_state['translation_entity']['key'] = 'language';
+    $form['language'] += translation_entity_enable_widget('user', 'user', $form, $form_state);
   }
 
   // User registration settings.
