diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
index a4f7019..f6bbf21 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TermAutocompleteController.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\field\FieldInfo;
 use Drupal\taxonomy\TermStorageControllerInterface;
+use Drupal\taxonomy\VocabularyInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
@@ -129,34 +130,82 @@ public function autocomplete(Request $request, $entity_type, $field_name) {
         $vids[] = $tree['vocabulary'];
       }
 
-      $this->termEntityQuery->addTag('term_access');
+      $matches = $this->getMatchingTerms($tags_typed, $vids, $tag_last);
+    }
 
-      // Do not select already entered terms.
-      if (!empty($tags_typed)) {
-        $this->termEntityQuery->condition('name', $tags_typed, 'NOT IN');
-      }
-      // Select rows that match by term name.
-      $tids = $this->termEntityQuery
-        ->condition('vid', $vids, 'IN')
-        ->condition('name', $tag_last, 'CONTAINS')
-        ->range(0, 10)
-        ->execute();
-
-      $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : '';
-      if (!empty($tids)) {
-        $terms = $this->termStorage->loadMultiple(array_keys($tids));
-        foreach ($terms as $term) {
-          $name = $term->label();
-          // Term names containing commas or quotes must be wrapped in quotes.
-          if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
-            $name = '"' . str_replace('"', '""', $name) . '"';
-          }
-          $matches[$prefix . $name] = String::checkPlain($term->label());
+    return new JsonResponse($matches);
+  }
+
+  /**
+   * Retrieves suggestions for taxonomy term autocompletion by vocabulary ID.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\taxonomy\VocabularyInterface $taxonomy_vocabulary
+   *   The vocabulary to filter by.
+   *
+   * @return \Symfony\Component\HttpFoundation\JsonResponse|\Symfony\Component\HttpFoundation\Response
+   *   When valid field name is specified, a JSON response containing the
+   *   autocomplete suggestions for taxonomy terms. Otherwise a normal response
+   *   containing an error message.
+   */
+  public function autocompletePerVid(Request $request, VocabularyInterface $taxonomy_vocabulary) {
+    // A comma-separated list of term names entered in the autocomplete form
+    // element. Only the last term is used for autocompletion.
+    $tags_typed = $request->query->get('q');
+    $tags_typed = Tags::explode($tags_typed);
+    $tag_last = Unicode::strtolower(array_pop($tags_typed));
+
+    $matches = array();
+    if ($tag_last != '') {
+      $vids = array($taxonomy_vocabulary->id());
+      $matches = $this->getMatchingTerms($tags_typed, $vids, $tag_last);
+    }
+    return new JsonResponse($matches);
+  }
+
+  /**
+   * Gets terms which matches some typed terms.
+   *
+   * @param string $tags_typed
+   *   The full typed tags string.
+   * @param array $vids
+   *   An array of vocabulary IDs which
+   * @param $tag_last
+   *   The lasted typed tag.
+   *
+   * @return array
+   *   Returns an array of matching terms.
+   */
+  protected function getMatchingTerms($tags_typed, array $vids, $tag_last) {
+    $matches = array();
+    $this->termEntityQuery->addTag('term_access');
+
+    // Do not select already entered terms.
+    if (!empty($tags_typed)) {
+      $this->termEntityQuery->condition('name', $tags_typed, 'NOT IN');
+    }
+    // Select rows that match by term name.
+    $tids = $this->termEntityQuery
+      ->condition('vid', $vids, 'IN')
+      ->condition('name', $tag_last, 'CONTAINS')
+      ->range(0, 10)
+      ->execute();
+
+    $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : '';
+    if (!empty($tids)) {
+      $terms = $this->termStorage->loadMultiple(array_keys($tids));
+      foreach ($terms as $term) {
+        $name = $term->label();
+        // Term names containing commas or quotes must be wrapped in quotes.
+        if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
+          $name = '"' . str_replace('"', '""', $name) . '"';
         }
+        $matches[$prefix . $name] = String::checkPlain($term->label());
       }
+      return $matches;
     }
-
-    return new JsonResponse($matches);
+    return $matches;
   }
 
 }
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/filter/TaxonomyIndexTid.php
index 9ef575f..72a66c7 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/filter/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/views/filter/TaxonomyIndexTid.php
@@ -127,7 +127,8 @@ protected function valueForm(&$form, &$form_state) {
       );
 
       if ($this->options['limit']) {
-        $form['value']['#autocomplete_path'] = 'admin/views/ajax/autocomplete/taxonomy/' . $vocabulary->id();
+        $form['value']['#autocomplete_route_name'] = 'taxonomy_autocomplete_vid';
+        $form['value']['#autocomplete_route_parameters'] = array('taxonomy_vocabulary' => $vocabulary->id());
       }
     }
     else {
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyIndexTidUiTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyIndexTidUiTest.php
index 1075d7b..17c8829 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyIndexTidUiTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/Views/TaxonomyIndexTidUiTest.php
@@ -93,6 +93,16 @@ public function testFilterUI() {
         $this->assertEqual($terms[$i][$j]->id(), $tid);
       }
     }
+
+    // Ensure the autocomplete input element appears when using the 'textfield'
+    // type.
+    $view = entity_load('view', 'test_filter_taxonomy_index_tid');
+    $display =& $view->getDisplay('default');
+    $display['display_options']['filters']['tid']['type'] = 'textfield';
+    $view->save();
+    $this->drupalGet('admin/structure/views/nojs/config-item/test_filter_taxonomy_index_tid/default/filter/tid');
+    $result = $this->xpath('//input[@id = "edit-options-value-autocomplete"]');
+    $this->assertEqual((string) $result[0]['value'], url('taxonomy/autocomplete_vid/tags'));
   }
 
 }
diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml
index 817c6f6..cb8f46f 100644
--- a/core/modules/taxonomy/taxonomy.routing.yml
+++ b/core/modules/taxonomy/taxonomy.routing.yml
@@ -61,6 +61,13 @@ taxonomy_autocomplete:
   requirements:
     _permission: 'access content'
 
+taxonomy_autocomplete_vid:
+  pattern: '/taxonomy/autocomplete_vid/{taxonomy_vocabulary}'
+  defaults:
+    _controller: '\Drupal\taxonomy\Controller\TermAutocompleteController::autocompletePerVid'
+  requirements:
+    _permission: 'access content'
+
 taxonomy_overview_terms:
   pattern: 'admin/structure/taxonomy/manage/{taxonomy_vocabulary}'
   defaults:
diff --git a/core/modules/views/includes/ajax.inc b/core/modules/views/includes/ajax.inc
index a662cc8..c3b493e 100644
--- a/core/modules/views/includes/ajax.inc
+++ b/core/modules/views/includes/ajax.inc
@@ -80,53 +80,5 @@ function views_ajax_form_wrapper($form_id, &$form_state) {
 }
 
 /**
- * Page callback for views taxonomy autocomplete.
- *
- * @param $vid
- *   The vocabulary id of the tags which should be returned.
- *
- * @see taxonomy_autocomplete()
- */
-function views_ajax_autocomplete_taxonomy($vid) {
-  // The user enters a comma-separated list of tags. We only autocomplete the
-  // last tag.
-  $tags_typed = Tags::explode(Drupal::request()->query->get('q'));
-  $tag_last = Unicode::strtolower(array_pop($tags_typed));
-  $term_matches = array();
-
-  if ($tag_last != '') {
-    $query = db_select('taxonomy_term_data', 't');
-    $query->addTag('term_access');
-
-    // Do not select already entered terms.
-    if (!empty($tags_typed)) {
-      $query->condition('t.name', $tags_typed, 'NOT IN');
-    }
-    // Select rows that match by term name.
-    $tags_return = $query
-      ->fields('t', array('tid', 'name'))
-      ->condition('t.vid', $vid)
-      ->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
-      ->range(0, 10)
-      ->execute()
-      ->fetchAllKeyed();
-
-    $prefix = count($tags_typed) ? Tags::implode($tags_typed) . ', ' : '';
-
-    foreach ($tags_return as $tid => $name) {
-      $n = $name;
-      // Term names containing commas or quotes must be wrapped in quotes.
-      if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
-        $n = '"' . str_replace('"', '""', $name) . '"';
-      }
-      // Add term name to list of matches.
-      $term_matches[$prefix . $n] = String::checkPlain($name);
-    }
-  }
-
-  return new JsonResponse($term_matches);
-}
-
-/**
  * @}
  */
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewsTaxonomyAutocompleteTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewsTaxonomyAutocompleteTest.php
index 6dec14c..ef5f98d 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewsTaxonomyAutocompleteTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewsTaxonomyAutocompleteTest.php
@@ -74,7 +74,7 @@ public function setUp() {
   public function testTaxonomyAutocomplete() {
     $this->user = $this->drupalCreateUser(array('access content'));
     $this->drupalLogin($this->user);
-    $base_autocomplete_path = 'admin/views/ajax/autocomplete/taxonomy/' . $this->vocabulary->vid;
+    $base_autocomplete_path = 'taxonomy/autocomplete_vid/' . $this->vocabulary->vid;
 
     // Test that no terms returns an empty array.
     $this->assertIdentical(array(), $this->drupalGetJSON($base_autocomplete_path));
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index e46f7fe..7ad8af4 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -322,17 +322,6 @@ function views_menu() {
     'route_name' => 'views_ajax',
     'type' => MENU_CALLBACK,
   );
-  // Define another taxonomy autocomplete because the default one of drupal
-  // does not support a vid a argument anymore
-  $items['admin/views/ajax/autocomplete/taxonomy/%'] = array(
-    'page callback' => 'views_ajax_autocomplete_taxonomy',
-    'page arguments' => array(5),
-    'theme callback' => 'ajax_base_page_theme',
-    'access callback' => 'user_access',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-    'file' => 'includes/ajax.inc',
-  );
   return $items;
 }
 
