diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Access/TaxonomyTermCreateAccess.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Access/TaxonomyTermCreateAccess.php
new file mode 100644
index 0000000..87ea3aa
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Access/TaxonomyTermCreateAccess.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\taxonomy\Access\TaxonomyTermCreateAccess.
+ */
+
+namespace Drupal\taxonomy\Access;
+
+use Drupal\Core\Entity\EntityCreateAccessCheck;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides an access check for taxonomy term creation.
+ */
+class TaxonomyTermCreateAccess extends EntityCreateAccessCheck {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $requirementsKey = '_access_taxonomy_term_create';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function prepareEntityValues(array $definition, Request $request, $bundle = NULL) {
+    $values = array();
+    if ($vocabulary = $request->attributes->get('taxonomy_vocabulary')) {
+      $values = parent::prepareEntityValues($definition, $request, $vocabulary->id());
+    }
+    return $values;
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php
new file mode 100644
index 0000000..74c3d12
--- /dev/null
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\taxonomy\Controller\TaxonomyController.
+ */
+
+namespace Drupal\taxonomy\Controller;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\taxonomy\TermStorageControllerInterface;
+use Drupal\taxonomy\VocabularyInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides route responses for taxonomy.module.
+ */
+class TaxonomyController implements ControllerInterface {
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManager
+   */
+  protected $entityManager;
+
+  /**
+   * The taxonomy term storage.
+   *
+   * @var \Drupal\taxonomy\TermStorageControllerInterface
+   */
+  protected $termStorage;
+
+  /**
+   * Constructs a new TaxonomyController.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
+   * @param \Drupal\taxonomy\TermStorageControllerInterface $term_storage
+   *   The taxonomy term storage.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler, EntityManager $entity_manager, TermStorageControllerInterface $term_storage) {
+    $this->moduleHandler = $module_handler;
+    $this->entityManager = $entity_manager;
+    $this->termStorage = $term_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    $entity_manager = $container->get('plugin.manager.entity');
+    return new static(
+      $container->get('module_handler'),
+      $entity_manager,
+      $entity_manager->getStorageController('taxonomy_term')
+    );
+  }
+
+  /**
+   * Returns a rendered edit form to create a new term associated to the given vocabulary.
+   *
+   * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary
+   *   The vocabulary this term will be added to.
+   *
+   * @return array
+   *   The taxonomy term add form.
+   */
+  public function addForm(VocabularyInterface $taxonomy_vocabulary) {
+    $term = $this->termStorage->create(array('vid' => $taxonomy_vocabulary->id()));
+    if ($this->moduleHandler->moduleExists('language')) {
+      $term->langcode = language_get_default_langcode('taxonomy_term', $taxonomy_vocabulary->id());
+    }
+    return $this->entityManager->getForm($term);
+  }
+
+}
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index 7db05ef..62defe2 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -391,17 +391,6 @@ function taxonomy_overview_terms_submit($form, &$form_state) {
 }
 
 /**
- * Returns a rendered edit form to create a new term associated to the given vocabulary.
- */
-function taxonomy_term_add($vocabulary) {
-  $term = entity_create('taxonomy_term', array('vid' => $vocabulary->id()));
-  if (module_exists('language')) {
-    $term->langcode = language_get_default_langcode('taxonomy_term', $vocabulary->id());
-  }
-  return Drupal::entityManager()->getForm($term);
-}
-
-/**
  * Form builder for the term delete form.
  *
  * @ingroup forms
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 8f57e16..8ddc389 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -329,31 +329,14 @@ function taxonomy_menu() {
 
   $items['admin/structure/taxonomy/manage/%taxonomy_vocabulary/add'] = array(
     'title' => 'Add term',
-    'page callback' => 'taxonomy_term_add',
-    'page arguments' => array(4),
-    'access callback' => 'taxonomy_term_create_access',
-    'access arguments' => array(4),
+    'route_name' => 'taxonomy_term_add',
     'type' => MENU_LOCAL_ACTION,
-    'file' => 'taxonomy.admin.inc',
   );
 
   return $items;
 }
 
 /**
- * Access callback for creating a new taxonomy term.
- *
- * @param \Drupal\taxonomy\Plugin\Core\Entity\Vocabulary $vocabulary
- *   The vocabulary entity that represents the term bundle.
- *
- * @return bool
- *   TRUE if access is allowed, FALSE if not.
- */
-function taxonomy_term_create_access(Vocabulary $vocabulary) {
-  return entity_page_create_access('taxonomy_term', $vocabulary->id());
-}
-
-/**
  * Implements hook_admin_paths().
  */
 function taxonomy_admin_paths() {
diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml
index 8715476..389ca7c 100644
--- a/core/modules/taxonomy/taxonomy.routing.yml
+++ b/core/modules/taxonomy/taxonomy.routing.yml
@@ -4,3 +4,10 @@ taxonomy_vocabulary_list:
     _entity_list: 'taxonomy_vocabulary'
   requirements:
     _permission: 'administer taxonomy'
+
+taxonomy_term_add:
+  pattern: '/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/add'
+  defaults:
+    _content: '\Drupal\taxonomy\Controller\TaxonomyController::addForm'
+  requirements:
+    _access_taxonomy_term_create: 'taxonomy_term'
diff --git a/core/modules/taxonomy/taxonomy.services.yml b/core/modules/taxonomy/taxonomy.services.yml
new file mode 100644
index 0000000..265eb5d
--- /dev/null
+++ b/core/modules/taxonomy/taxonomy.services.yml
@@ -0,0 +1,6 @@
+services:
+  access_check.taxonomy_term.create:
+    class: Drupal\taxonomy\Access\TaxonomyTermCreateAccess
+    arguments: ['@plugin.manager.entity']
+    tags:
+      - { name: access_check }
