diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 979419e..47eea47 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -214,47 +214,6 @@ function language_admin_edit_form_submit($form, &$form_state) {
 }
 
 /**
- * User interface for the language deletion confirmation screen.
- */
-function language_admin_delete_form($form, &$form_state, $language) {
-  $langcode = $language->id;
-
-  if (language_default()->id == $langcode) {
-    drupal_set_message(t('The default language cannot be deleted.'));
-    return new RedirectResponse(url('admin/config/regional/language', array('absolute' => TRUE)));
-  }
-
-  // For other languages, warn the user that data loss is ahead.
-  $languages = language_list();
-
-  if (!isset($languages[$langcode])) {
-    throw new NotFoundHttpException();
-  }
-  else {
-    $form['langcode'] = array('#type' => 'value', '#value' => $langcode);
-    return confirm_form($form, t('Are you sure you want to delete the language %language?', array('%language' => $languages[$langcode]->name)), 'admin/config/regional/language', t('Deleting a language will remove all interface translations associated with it, and posts in this language will be set to be language neutral. This action cannot be undone.'), t('Delete'), t('Cancel'));
-  }
-}
-
-/**
- * Process language deletion submissions.
- */
-function language_admin_delete_form_submit($form, &$form_state) {
-  $langcode = $form_state['values']['langcode'];
-  $languages = language_list();
-  $language = $languages[$langcode];
-
-  $success = language_delete($langcode);
-
-  if ($success) {
-    $t_args = array('%language' => $language->name, '%langcode' => $language->id);
-    drupal_set_message(t('The %language (%langcode) language has been removed.', $t_args));
-  }
-
-  $form_state['redirect'] = 'admin/config/regional/language';
-}
-
-/**
  * Prepare a language code list for unused predefined languages.
  */
 function language_admin_predefined_list() {
@@ -712,31 +671,6 @@ function language_negotiation_configure_browser_form_submit($form, &$form_state)
 }
 
 /**
- * Form for deleting a browser language negotiation mapping.
- */
-function language_negotiation_configure_browser_delete_form($form, &$form_state, $browser_langcode) {
-  $form_state['browser_langcode'] = $browser_langcode;
-  $question = t('Are you sure you want to delete %browser_langcode?', array(
-    '%browser_langcode' => $browser_langcode,
-  ));
-  $path = 'admin/config/regional/language/detection/browser';
-  return confirm_form($form, $question, $path, '');
-}
-
-/**
- * Form submit handler to delete a browser language negotiation mapping.
- */
-function language_negotiation_configure_browser_delete_form_submit($form, &$form_state) {
-  $browser_langcode = $form_state['browser_langcode'];
-  $mappings = language_get_browser_drupal_langcode_mappings();
-  if (array_key_exists($browser_langcode, $mappings)) {
-    unset($mappings[$browser_langcode]);
-    language_set_browser_drupal_langcode_mappings($mappings);
-  }
-  $form_state['redirect'] = 'admin/config/regional/language/detection/browser';
-}
-
-/**
  * Returns the content language settings form.
  */
 function language_content_settings_page() {
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 4d2688c..ffdb256 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -94,12 +94,7 @@ function language_menu() {
     'file' => 'language.admin.inc',
   );
   $items['admin/config/regional/language/delete/%language'] = array(
-    'title' => 'Confirm delete',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('language_admin_delete_form', 5),
-    'access callback' => 'language_access_language_edit_or_delete',
-    'access arguments' => array(5),
-    'file' => 'language.admin.inc',
+    'route_name' => 'language_admin_delete',
   );
 
   // Language negotiation.
@@ -130,13 +125,6 @@ function language_menu() {
     'file' => 'language.admin.inc',
     'type' => MENU_VISIBLE_IN_BREADCRUMB,
   );
-  $items['admin/config/regional/language/detection/browser/delete/%'] = array(
-    'title' => 'Delete language mapping',
-    'page arguments' => array('language_negotiation_configure_browser_delete_form', 7),
-    'type' => MENU_CALLBACK,
-    'access arguments' => array('administer languages'),
-    'file' => 'language.admin.inc',
-  );
   $items['admin/config/regional/language/detection/selected'] = array(
     'title' => 'Selected language detection configuration',
     'route_name' => 'language_negotiation_selected',
@@ -880,3 +868,10 @@ function language_system_regional_settings_form_submit($form, &$form_state) {
   $language->default = TRUE;
   language_save($language);
 }
+
+/**
+ * Implements hook_entity_info().
+ */
+function language_entity_info(&$entity_info) {
+  $entity_info['language_entity']['controllers']['form']['delete'] = 'Drupal\language\Form\LanguageDeleteForm';
+}
diff --git a/core/modules/language/language.routing.yml b/core/modules/language/language.routing.yml
index e75e1ce..2f1b8af 100644
--- a/core/modules/language/language.routing.yml
+++ b/core/modules/language/language.routing.yml
@@ -25,3 +25,17 @@ language_admin_overview:
     _entity_list: 'language_entity'
   requirements:
     _permission: 'administer languages'
+
+language_admin_delete:
+  pattern: '/admin/config/regional/language/delete/{language_entity}'
+  defaults:
+    _entity_form: 'language_entity.delete'
+  requirements:
+    _entity_access: 'language_entity.delete'
+
+language_negotiation_browser_delete:
+  pattern: 'admin/config/regional/language/detection/browser/delete/{browser_langcode}'
+  defaults:
+    _form: '\Drupal\language\Form\NegotiationBrowserDeleteForm'
+  requirements:
+    _permission: 'administer languages'
diff --git a/core/modules/language/lib/Drupal/language/Form/LanguageDeleteForm.php b/core/modules/language/lib/Drupal/language/Form/LanguageDeleteForm.php
new file mode 100644
index 0000000..a2da23c
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Form/LanguageDeleteForm.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Form\LanguageDeleteForm.
+ */
+
+namespace Drupal\language\Form;
+
+use Drupal\Core\Entity\EntityConfirmFormBase;
+use Drupal\Core\Entity\EntityControllerInterface;
+use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Routing\PathBasedGeneratorInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+/**
+ * Defines a confirmation form for deleting a language entity.
+ */
+class LanguageDeleteForm extends EntityConfirmFormBase implements EntityControllerInterface {
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManager
+   */
+  protected $entityManager;
+
+  /**
+   * The urlGenerator service.
+   *
+   * @var \Drupal\Core\Routing\PathBasedGeneratorInterface
+   */
+  protected $urlGenerator;
+
+  /**
+   * Constructs a new LanguageDeleteForm object.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler, EntityManager $entity_manager, \Drupal\Core\Routing\PathBasedGeneratorInterface $url_generator) {
+    parent::__construct($module_handler);
+    $this->entityManager = $entity_manager;
+    $this->urlGenerator = $url_generator;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
+    return new static(
+      $container->get('module_handler'),
+      $container->get('plugin.manager.entity'),
+      $container->get('url_generator')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return t('Are you sure you want to delete the language %language?', array('%language' => $this->entity->get('label')));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelPath() {
+    return 'admin/config/regional/language';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return t('Deleting a language will remove all interface translations associated with it, and content in this language will be set to be language neutral. This action cannot be undone.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return t('Delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'language_admin_delete_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state, Request $request = NULL) {
+
+    $langcode = $this->entity->id();
+
+    // Warn and redirect user when attempting to delete the default language.
+    if (language_default()->id == $langcode) {
+      drupal_set_message(t('The default language cannot be deleted.'));
+      $url = $this->urlGenerator->generateFromPath('admin/config/regional/language', array('absolute' => TRUE));
+      return new RedirectResponse($url);
+    }
+
+    // Throw a 404 when attempting to delete a non-existing language.
+    $languages = language_list();
+    if (!isset($languages[$langcode])) {
+      throw new NotFoundHttpException();
+    }
+    else {
+      return parent::buildForm($form, $form_state, $request);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submit(array $form, array &$form_state) {
+    $success = language_delete($this->entity->id());
+
+    if ($success) {
+      $t_args = array('%language' => $this->entity->get('label'), '%langcode' => $this->entity->id());
+      drupal_set_message(t('The %language (%langcode) language has been removed.', $t_args));
+    }
+
+    $form_state['redirect'] = 'admin/config/regional/language';
+  }
+}
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserDeleteForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserDeleteForm.php
new file mode 100644
index 0000000..cb159e6
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationBrowserDeleteForm.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language\Form\NegotiationConfigureBrowserDeleteForm.
+ */
+
+namespace Drupal\language\Form;
+
+use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\core\Language\Language;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines a confirmation form for deleting a browser language negotiation mapping.
+ */
+class NegotiationBrowserDeleteForm extends ConfirmFormBase {
+
+  /**
+   * The browser language code to be deleted.
+   *
+   * @var string
+   */
+  protected $browserLangcode;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return t('Are you sure you want to delete %browser_langcode?', array(
+      '%browser_langcode' => $this->browserLangcode,
+    ));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelPath() {
+    return 'admin/config/regional/language/detection/browser';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'language_negotiation_configure_browser_delete_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state, $browser_langcode = NULL, Request $request = NULL) {
+    $this->browserLangcode = $browser_langcode;
+
+    return parent::buildForm($form, $form_state, $request);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    $mappings = language_get_browser_drupal_langcode_mappings();
+
+    if (array_key_exists($this->browserLangcode, $mappings)) {
+      unset($mappings[$this->browserLangcode]);
+      language_set_browser_drupal_langcode_mappings($mappings);
+    }
+
+    $form_state['redirect'] = 'admin/config/regional/language/detection/browser';
+  }
+}
