diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
index 9ec9758..d383b8b 100644
--- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
+++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
@@ -123,6 +123,11 @@ views.filter.taxonomy_index_tid:
     vid:
       type: string
       label: 'Vocabulary'
+    vids:
+      type: sequence
+      sequence:
+        label: 'Vocabulary'
+        type: string
     type:
       type: string
       label: 'Selection type'
diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
index 0158881..bd0c953 100644
--- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\taxonomy\Entity\Term;
 use Drupal\taxonomy\TermStorageInterface;
+use Drupal\taxonomy\VocabularyInterface;
 use Drupal\taxonomy\VocabularyStorageInterface;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -78,7 +79,10 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
     parent::init($view, $display, $options);
 
     if (!empty($this->definition['vocabulary'])) {
-      $this->options['vid'] = $this->definition['vocabulary'];
+      $this->options['vids'] = [$this->definition['vocabulary']];
+    }
+    if (empty($this->options['vids']) && !empty($this->options['vid'])) {
+      $this->options['vids'] = [$this->options['vid']];
     }
   }
 
@@ -96,13 +100,16 @@ protected function defineOptions() {
 
     $options['type'] = array('default' => 'textfield');
     $options['limit'] = array('default' => TRUE);
-    $options['vid'] = array('default' => '');
+    $options['vids'] = array('default' => []);
     $options['hierarchy'] = array('default' => FALSE);
     $options['error_message'] = array('default' => TRUE);
 
     return $options;
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {
     $vocabularies = $this->vocabularyStorage->loadMultiple();
     $options = array();
@@ -112,18 +119,19 @@ public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {
 
     if ($this->options['limit']) {
       // We only do this when the form is displayed.
-      if (empty($this->options['vid'])) {
+      if (empty($this->options['vids'])) {
         $first_vocabulary = reset($vocabularies);
-        $this->options['vid'] = $first_vocabulary->id();
+        $this->options['vids'] = [$first_vocabulary->id()];
       }
 
       if (empty($this->definition['vocabulary'])) {
-        $form['vid'] = array(
-          '#type' => 'radios',
+        $form['vids'] = array(
+          '#type' => 'checkboxes',
           '#title' => $this->t('Vocabulary'),
           '#options' => $options,
           '#description' => $this->t('Select which vocabulary to show terms for in the regular options.'),
-          '#default_value' => $this->options['vid'],
+          '#default_value' => $this->options['vids'],
+          '#required' => TRUE,
         );
       }
     }
@@ -147,9 +155,33 @@ public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {
     );
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateExtraOptionsForm($form, FormStateInterface $form_state) {
+    parent::validateExtraOptionsForm($form, $form_state);
+
+    // Don't allow to select more than one vocabulary when 'select' is chosen.
+    $vids = $form_state->getValue(['options', 'vids']);
+    $selection_type = $form_state->getValue(['options', 'type']);
+    if ($selection_type === 'select' && count($vids) > 1) {
+      $form_state->setErrorByName('options][vids', $this->t("You cannot select more than one vocabulary, when choosing 'Dropdown' as selection type."));
+    }
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitExtraOptionsForm($form, FormStateInterface $form_state) {
+    $vids = $form_state->getValue(['options', 'vids']);
+    $form_state->setValue(['options', 'vids'], array_keys(array_filter($vids)));
+  }
+
   protected function valueForm(&$form, FormStateInterface $form_state) {
-    $vocabulary = $this->vocabularyStorage->load($this->options['vid']);
-    if (empty($vocabulary) && $this->options['limit']) {
+    $vocabularies = $this->vocabularyStorage->loadMultiple($this->options['vids']);
+    $vocabulary = reset($vocabularies);
+    if (empty($vocabularies) && $this->options['limit']) {
       $form['markup'] = array(
         '#markup' => '<div class="js-form-item form-item">' . $this->t('An invalid vocabulary is selected. Please change it in the options.') . '</div>',
       );
@@ -158,8 +190,11 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
 
     if ($this->options['type'] == 'textfield') {
       $terms = $this->value ? Term::loadMultiple(($this->value)) : array();
+      $vocabulary_labels = array_map(function (VocabularyInterface $vocabulary) {
+        return $vocabulary->label();
+      }, $vocabularies);
       $form['value'] = array(
-        '#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->label())) : $this->t('Select terms'),
+        '#title' => $this->options['limit'] ? $this->t('Select terms from vocabularies @vocs', array('@vocs' => implode(', ', $vocabulary_labels))) : $this->t('Select terms'),
         '#type' => 'textfield',
         '#default_value' => EntityAutocomplete::getEntityLabels($terms),
       );
@@ -167,7 +202,7 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
       if ($this->options['limit']) {
         $form['value']['#type'] = 'entity_autocomplete';
         $form['value']['#target_type'] = 'taxonomy_term';
-        $form['value']['#selection_settings']['target_bundles'] = array($vocabulary->id());
+        $form['value']['#selection_settings']['target_bundles'] = array_keys($vocabularies);
         $form['value']['#tags'] = TRUE;
         $form['value']['#process_default_value'] = FALSE;
       }
@@ -388,8 +423,10 @@ public function getCacheContexts() {
   public function calculateDependencies() {
     $dependencies = parent::calculateDependencies();
 
-    $vocabulary = $this->vocabularyStorage->load($this->options['vid']);
-    $dependencies[$vocabulary->getConfigDependencyKey()][] = $vocabulary->getConfigDependencyName();
+    $vocabularies = $this->vocabularyStorage->loadMultiple($this->options['vids']);
+    foreach ($vocabularies as $vocabulary) {
+      $dependencies[$vocabulary->getConfigDependencyKey()][] = $vocabulary->getConfigDependencyName();
+    }
 
     foreach ($this->termStorage->loadMultiple($this->options['value']) as $term) {
       $dependencies[$term->getConfigDependencyKey()][] = $term->getConfigDependencyName();
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php
index 7dff50a..d1ced88 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyIndexTidUiTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\taxonomy\Tests\Views;
 
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
+use Drupal\node\Entity\Node;
 use Drupal\taxonomy\Entity\Term;
 use Drupal\taxonomy\Entity\Vocabulary;
 use Drupal\views\Tests\ViewTestData;
@@ -49,9 +50,27 @@ protected function setUp() {
     $this->adminUser = $this->drupalCreateUser(['administer taxonomy', 'administer views']);
     $this->drupalLogin($this->adminUser);
 
+    $this->terms = $this->createVocabularyAndTerms('tags');
+    ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views'));
+
     Vocabulary::create([
-      'vid' => 'tags',
-      'name' => 'Tags',
+      'vid' => 'empty_vocabulary',
+      'name' => 'Empty Vocabulary',
+    ])->save();
+  }
+
+  /**
+   * Creates a vocabulary and terms for it.
+   *
+   * @param string $vocab_id
+   *   The vocabulary ID.
+   *
+   * @return \Drupal\taxonomy\TermInterface[][]
+   */
+  protected function createVocabularyAndTerms($vocab_id) {
+    Vocabulary::create([
+      'vid' => $vocab_id,
+      'name' => $vocab_id,
     ])->save();
 
     // Setup a hierarchy which looks like this:
@@ -61,22 +80,18 @@ protected function setUp() {
     // term 2.0
     // - term 2.1
     // - term 2.2
+    $terms = [];
     for ($i = 0; $i < 3; $i++) {
       for ($j = 0; $j <= $i; $j++) {
-        $this->terms[$i][$j] = $term = Term::create([
-          'vid' => 'tags',
+        $terms[$i][$j] = $term = Term::create([
+          'vid' => $vocab_id,
           'name' => "Term $i.$j",
           'parent' => isset($terms[$i][0]) ? $terms[$i][0]->id() : 0,
         ]);
         $term->save();
       }
     }
-    ViewTestData::createTestViews(get_class($this), array('taxonomy_test_views'));
-
-    Vocabulary::create([
-      'vid' => 'empty_vocabulary',
-      'name' => 'Empty Vocabulary',
-    ])->save();
+    return $terms;
   }
 
   /**
@@ -127,6 +142,81 @@ public function testFilterUI() {
     $this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
   }
 
+  public function testFilterUIWithMoreVocabularies() {
+    $terms2 = $this->createVocabularyAndTerms('tags2');
+
+    $node_type = $this->drupalCreateContentType(['type' => 'page']);
+
+    // Create the tag field itself.
+    $field_name = 'taxonomy_tags';
+    $this->createEntityReferenceField('node', $node_type->id(), $field_name, NULL, 'taxonomy_term');
+
+    $node0 = $this->drupalCreateNode([
+      'type' => 'page',
+      'taxonomy_tags' => $this->terms[0][0]->id(),
+    ]);
+    $node0->save();
+    $node1 = $this->drupalCreateNode([
+      'type' => 'page',
+      'taxonomy_tags' => $terms2[0][0]->id(),
+    ]);
+    $node1->save();
+    $node2 = $this->drupalCreateNode([
+      'type' => 'page',
+      'taxonomy_tags' => [$this->terms[0][0]->id(), $terms2[0][0]->id()],
+    ]);
+    $node2->save();
+
+    $edit = [
+      'options[vids][tags]' => TRUE,
+      'options[vids][tags2]' => TRUE,
+      'options[type]' => 'select',
+    ];
+    $this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_filter_taxonomy_index_tid/default/filter/tid', $edit, 'Apply');
+    $this->assertText("You cannot select more than one vocabulary, when choosing 'Dropdown' as selection type.");
+
+    $edit = [
+      'options[vids][tags]' => TRUE,
+      'options[vids][tags2]' => TRUE,
+      'options[type]' => 'textfield',
+    ];
+    $this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_filter_taxonomy_index_tid/default/filter/tid', $edit, 'Apply');
+    $this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid', [], 'Expose filter');
+    $edit = [
+      'options[operator]' => 'and',
+      'options[value]' => '',
+      'options[reduce_duplicates]' => TRUE
+    ];
+    $this->drupalPostForm(NULL, $edit, 'Apply');
+    $this->drupalPostForm(NULL, [], 'Save');
+
+    $this->drupalGet('test-filter-taxonomy-index-tid', ['query' => ['tid' => '']]);
+    $xpath = $this->xpath('//div[@class="view-content"]//a');
+    $this->assertIdentical(3, count($xpath));
+
+    $this->drupalGet('test-filter-taxonomy-index-tid', ['query' => ['tid' => "t1 ({$this->terms[0][0]->id()})"]]);
+    $xpath = $this->xpath('//div[@class="view-content"]//a');
+    $this->assertIdentical(2, count($xpath));
+    $xpath = $this->xpath('//div[@class="view-content"]//a[@href=:href]', [':href' => $node0->toUrl()->toString()]);
+    $this->assertIdentical(1, count($xpath));
+    $xpath = $this->xpath('//div[@class="view-content"]//a[@href=:href]', [':href' => $node2->toUrl()->toString()]);
+    $this->assertIdentical(1, count($xpath));
+
+    $this->drupalGet('test-filter-taxonomy-index-tid', ['query' => ['tid' => "t2 ({$terms2[0][0]->id()})"]]);
+    $xpath = $this->xpath('//div[@class="view-content"]//a');
+    $this->assertIdentical(2, count($xpath));
+    $xpath = $this->xpath('//div[@class="view-content"]//a[@href=:href]', [':href' => $node1->toUrl()->toString()]);
+    $this->assertIdentical(1, count($xpath));
+    $xpath = $this->xpath('//div[@class="view-content"]//a[@href=:href]', [':href' => $node2->toUrl()->toString()]);
+    $this->assertIdentical(1, count($xpath));
+
+    $this->drupalGet('test-filter-taxonomy-index-tid', ['query' => ['tid' => "t1 ({$this->terms[0][0]->id()}), t2 ({$terms2[0][0]->id()})"]]);
+    $xpath = $this->xpath('//div[@class="view-content"]//a');
+    $this->assertIdentical(1, count($xpath));
+    $xpath = $this->xpath('//div[@class="view-content"]//a[@href=:href]', [':href' => $node2->toUrl()->toString()]);
+    $this->assertIdentical(1, count($xpath));
+  }
+
   /**
    * Tests exposed taxonomy filters.
    */
diff --git a/core/modules/taxonomy/src/Tests/Views/Update/TaxonomyIndexTidUpdateTest.php b/core/modules/taxonomy/src/Tests/Views/Update/TaxonomyIndexTidUpdateTest.php
new file mode 100644
index 0000000..ea3669a
--- /dev/null
+++ b/core/modules/taxonomy/src/Tests/Views/Update/TaxonomyIndexTidUpdateTest.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\taxonomy\Tests\views\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\views\Entity\View;
+
+/**
+ * Tests the conversion from vid to vids in taxonomy_index_tid.
+ *
+ * @see taxonomy_post_update_taxonomy_index_filter_multiple_vocabularies()
+ *
+ * @group Update
+ */
+class TaxonomyIndexTidUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
+      __DIR__ . '/../../../../tests/fixtures/update/taxonomy-index-filter-multiple-vocabularies.php',
+    ];
+  }
+
+  /**
+   * Tests that field handlers are updated properly.
+   */
+  public function testPostUpdateTaxonomyIndexFilterMultipleVocabularies() {
+    $this->runUpdates();
+
+    // Load and initialize our test view.
+    $view = View::load('test_filter_taxonomy_index_tid_pre_update');
+    $data = $view->toArray();
+    // Check that the field is using the expected base table.
+    $this->assertEqual(['tags'], $data['display']['default']['display_options']['filters']['tid']['vids']);
+    $this->assertTrue(empty($data['display']['default']['display_options']['filters']['tid']['vid']));
+  }
+
+}
diff --git a/core/modules/taxonomy/taxonomy.post_update.php b/core/modules/taxonomy/taxonomy.post_update.php
new file mode 100644
index 0000000..2f4c98e
--- /dev/null
+++ b/core/modules/taxonomy/taxonomy.post_update.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @addtogroup updates-8.3.0
+ * @{
+ */
+
+/**
+ * Update the cacheability metadata for all views.
+ */
+function taxonomy_post_update_taxonomy_index_filter_multiple_vocabularies() {
+  // Load all views.
+  $views = \Drupal::entityTypeManager()->getStorage('view')->loadMultiple();
+
+  /* @var \Drupal\views\Entity\View[] $views */
+  foreach ($views as $view) {
+    $save = FALSE;
+    $displays = $view->get('display');
+    foreach (array_keys($displays) as $display_id) {
+      $display =& $view->getDisplay($display_id);
+      if (!empty($display['display_options']['filters'])) {
+        foreach ($display['display_options']['filters'] as &$filter) {
+          if ($filter['plugin_id'] === 'taxonomy_index_tid' && empty($filter['vids']) && !empty($filter['vid'])) {
+            $filter['vids'] = [$filter['vid']];
+            unset($filter['vid']);
+            $save = TRUE;
+          }
+        }
+      }
+    }
+    if ($save) {
+      $view->save();
+    }
+  }
+
+}
+
+/**
+ * @} End of "addtogroup updates-8.3.0
+ */
+
diff --git a/core/modules/taxonomy/tests/fixtures/update/taxonomy-index-filter-multiple-vocabularies.php b/core/modules/taxonomy/tests/fixtures/update/taxonomy-index-filter-multiple-vocabularies.php
new file mode 100644
index 0000000..5e77c1d
--- /dev/null
+++ b/core/modules/taxonomy/tests/fixtures/update/taxonomy-index-filter-multiple-vocabularies.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Test fixture.
+ */
+
+use Drupal\Core\Database\Database;
+use Drupal\Core\Serialization\Yaml;
+
+$connection = Database::getConnection();
+
+$connection->insert('config')
+  ->fields(array(
+    'collection' => '',
+    'name' => 'views.view.test_filter_taxonomy_index_tid_pre_update',
+    'data' => serialize(Yaml::decode(file_get_contents('core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_pre_update.yml'))),
+  ))
+  ->execute();
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
index 028d6d5..14e2732 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
@@ -166,7 +166,8 @@ display:
           reduce_duplicates: false
           type: select
           limit: true
-          vid: tags
+          vids:
+            - tags
           hierarchy: true
           error_message: true
           plugin_id: taxonomy_index_tid
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid__non_existing_dependency.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid__non_existing_dependency.yml
index 46c4a339..4377280 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid__non_existing_dependency.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid__non_existing_dependency.yml
@@ -167,7 +167,8 @@ display:
           reduce_duplicates: false
           type: select
           limit: true
-          vid: tags
+          vids:
+            - tags
           hierarchy: true
           error_message: true
           plugin_id: taxonomy_index_tid
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
index da366c5..333bafd 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
@@ -165,7 +165,8 @@ display:
           reduce_duplicates: false
           type: select
           limit: true
-          vid: views_testing_tags
+          vids:
+            - views_testing_tags
           hierarchy: true
           depth: -2
           error_message: true
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_pre_update.yml
similarity index 97%
copy from core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
copy to core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_pre_update.yml
index 028d6d5..112a7ac 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_pre_update.yml
@@ -5,8 +5,8 @@ dependencies:
     - node
     - taxonomy
     - user
-id: test_filter_taxonomy_index_tid
-label: test_filter_taxonomy_index_tid
+id: test_filter_taxonomy_index_tid_pre_update
+label: test_filter_taxonomy_index_tid_pre_update
 module: views
 description: ''
 tag: ''
diff --git a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
index 0c10fb1..f2df045 100644
--- a/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
+++ b/core/modules/views_ui/src/Form/Ajax/ConfigHandlerExtra.php
@@ -93,6 +93,10 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
     $form_state->get('handler')->validateExtraOptionsForm($form['options'], $form_state);
+
+    if ($form_state->getErrors()) {
+      $form_state->set('rerender', TRUE);
+    }
   }
 
   /**
