diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 25e9b9a..4ea8238 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2710,13 +2710,14 @@ function language_list($flags = LANGUAGE_CONFIGURABLE) {
     $default = language_default();
     if (language_multilingual() || module_exists('language')) {
       // Use language module configuration if available.
-      $languages = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode', PDO::FETCH_ASSOC);
+      $languages = entity_load_multiple('language');
 
       // Initialize default property so callers have an easy reference and can
       // save the same object without data loss.
-      foreach ($languages as $langcode => $info) {
+      foreach ($languages as $info) {
+        $langcode = $info['langcode'];
         $info['default'] = ($langcode == $default->langcode);
-        $languages[$langcode] = new Language($info);
+        $languages[$langcode] = new Language($info->getExportProperties());
       }
     }
     else {
diff --git a/core/modules/language/language.install b/core/modules/language/language.install
index b16c53b..243e166 100644
--- a/core/modules/language/language.install
+++ b/core/modules/language/language.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for the language module.
  */
 
+use Drupal\Component\Uuid\Uuid;
+
 /**
  * Implements hook_install().
  *
@@ -51,55 +53,6 @@ function language_uninstall() {
 }
 
 /**
- * Implements hook_schema().
- */
-function language_schema() {
-  $schema['language'] = array(
-    'description' => 'List of all available languages in the system.',
-    'fields' => array(
-      'langcode' => array(
-        'type' => 'varchar',
-        'length' => 12,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => "Language code, e.g. 'de' or 'en-US'.",
-      ),
-      'name' => array(
-        'type' => 'varchar',
-        'length' => 64,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Language name.',
-      ),
-      'direction' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Direction of language (Left-to-Right = 0, Right-to-Left = 1).',
-      ),
-      'weight' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Weight, used in lists of languages.',
-      ),
-      'locked' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'A boolean indicating whether the administrator can edit or delete the language.',
-      ),
-    ),
-    'primary key' => array('langcode'),
-    'indexes' => array(
-      'list' => array('weight', 'name'),
-    ),
-  );
-  return $schema;
-}
-
-/**
  * Implements hook_enable().
  */
 function language_enable() {
@@ -117,3 +70,32 @@ function language_disable() {
   // will be FALSE, because the language module is disabled.
   variable_set('language_count', 1);
 }
+
+/**
+ * Migrate all languages to configuration.
+ *
+ * @ingroup config_upgrade
+ */
+function language_update_8000() {
+  $manifest_ids = array();
+  $result = db_query('SELECT * FROM {language}');
+  $uuid = new Uuid();
+  foreach ($result as $language) {
+
+    config('language.' . $language->langcode)
+      ->set('id', $language->langcode)
+      ->set('name', $language->name)
+      ->set('direction', $language->direction)
+      ->set('weight', $language->weight)
+      ->set('locked', $language->locked)
+      ->set('langcode', LANGUAGE_NOT_SPECIFIED)
+      ->set('uuid', $uuid->generate())
+      ->save();
+
+    $manifest_ids[] = $language->langcode;
+  }
+
+  if (!empty($manifest_ids)) {
+    update_config_manifest_add('language.entity', $manifest_ids);
+  }
+}
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 6bbb5a7..f32b625 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -469,10 +469,11 @@ function language_get_default_langcode($entity_type, $bundle) {
  * API function to add or update a language.
  *
  * @param $language
- *   Language object with properties corresponding to 'language' table columns.
+ *   Language object with properties corresponding to the
+ *   'language' configuration properties.
  */
 function language_save($language) {
-  $language->is_new = !(bool) db_query_range('SELECT 1 FROM {language} WHERE langcode = :langcode', 0, 1, array(':langcode' => $language->langcode))->fetchField();
+  $language->is_new = entity_load('language', $language->langcode);
 
   // Let other modules modify $language before saved.
   module_invoke_all('language_presave', $language);
@@ -480,12 +481,22 @@ function language_save($language) {
   // Save the record and inform others about the change.
   $t_args = array('%language' => $language->name, '%langcode' => $language->langcode);
   if ($language->is_new) {
-    drupal_write_record('language', $language);
+    entity_create('language', array(
+      'langcode' => $language->langcode,
+      'name' => $language->name,
+      'direction' => $language->direction,
+      'weight' => $language->weight,
+      'locked' => FALSE,
+    ))->save();
     module_invoke_all('language_insert', $language);
     watchdog('language', 'The %language (%langcode) language has been created.', $t_args);
   }
   else {
-    drupal_write_record('language', $language, array('langcode'));
+    config('language.' . $language->langcode)
+      ->set('name', $language->name)
+      ->set('direction', $language->direction)
+      ->set('weight', $language->weight)
+      ->save();
     module_invoke_all('language_update', $language);
     watchdog('language', 'The %language (%langcode) language has been updated.', $t_args);
   }
@@ -521,7 +532,14 @@ function language_save($language) {
  * @see language_multilingual()
  */
 function language_update_count() {
-  variable_set('language_count', db_query('SELECT COUNT(langcode) FROM {language} WHERE locked = 0')->fetchField());
+  $count = 0;
+  $languages = entity_load_multiple('language', NULL, TRUE);
+  foreach ($languages as $language) {
+    if (!$language->locked) {
+      $count++;
+    }
+  }
+  variable_set('language_count', $count);
 }
 
 /**
@@ -541,9 +559,7 @@ function language_delete($langcode) {
     module_invoke_all('language_delete', $language);
 
     // Remove the language.
-    db_delete('language')
-      ->condition('langcode', $language->langcode)
-      ->execute();
+    entity_delete_multiple('language', array($language->langcode));
 
     language_update_count();
 
@@ -850,6 +866,8 @@ function language_set_browser_drupal_langcode_mappings($mappings) {
  * Updates locked system language weights.
  */
 function language_update_locked_weights() {
+  // @todo fix this.
+  return;
   // Get maximum weight to update the system languages to keep them on bottom.
   $max_weight = db_query('SELECT MAX(weight) FROM {language} WHERE locked = 0')->fetchField();
   // Loop locked languages to maintain the existing order.
diff --git a/core/modules/language/lib/Drupal/language/Plugin/Core/Entity/Language.php b/core/modules/language/lib/Drupal/language/Plugin/Core/Entity/Language.php
new file mode 100644
index 0000000..a6771e1
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Entity/Language.php
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Plugin\Core\Entity\Language.
+ */
+
+namespace Drupal\language\Plugin\Core\Entity;
+
+use Drupal\Core\Entity\Annotation\EntityType;
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+
+/**
+ * Defines the Language entity.
+ *
+ * @EntityType(
+ *   id = "language",
+ *   label = @Translation("Language"),
+ *   module = "language",
+ *   controllers = {
+ *     "storage" = "Drupal\Core\Config\Entity\ConfigStorageController"
+ *   },
+ *   config_prefix = "language",
+ *   entity_keys = {
+ *     "id" = "langcode",
+ *     "label" = "name",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class Language extends ConfigEntityBase implements \ArrayAccess {
+
+  /**
+   * The language ID (machine name).
+   *
+   * @var string
+   */
+  public $langcode;
+
+  /**
+   * The language UUID.
+   *
+   * This is assigned automatically when the language is created.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The human-readable label for the language.
+   *
+   * @var string
+   */
+  public $name;
+
+  /**
+   * The direction of language (Left-to-Right = 0, Right-to-Left = 1).
+   *
+   * @var integer
+   */
+  public $direction = '';
+
+  /**
+   * The weight of the language, used in lists of languages.
+   *
+   * @var integer
+   */
+  public $weight = 0;
+
+  /**
+   * Flag indicating whether this language is locked or not.
+   *
+   * @var bool
+   */
+  public $locked = FALSE;
+
+  /**
+   * Overrides Drupal\Core\Entity\Entity::id().
+   */
+  public function id() {
+    return $this->langcode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function offsetExists($offset) {
+    return isset($this->{$offset});
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &offsetGet($offset) {
+    return $this->{$offset};
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function offsetSet($offset, $value) {
+    $this->{$offset} = $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function offsetUnset($offset) {
+    unset($this->{$offset});
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
index e561ab7..7380c20 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
@@ -39,8 +39,9 @@ function testEnableWithoutDependency() {
 
     $this->assertModules(array('translation_entity', 'language'), TRUE);
 
-    // Assert that the language tables were enabled.
-    $this->assertTableCount('language', TRUE);
+    // Assert that the language YAML files were created.
+    $storage = drupal_container()->get('config.storage');
+    $this->assertTrue(count($storage->listAll('language.entity.')) > 0, 'Language config entity files exist.');
   }
 
   /**
