diff --git a/core/includes/form.inc b/core/includes/form.inc
index 8aee8f0..ed3ca33 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -1909,6 +1909,23 @@ function form_builder($form_id, &$element, &$form_state) {
     $element['#processed'] = TRUE;
   }
 
+  // Checks if the element needs property validation.
+  if (isset($element['#property_validate']) && is_array($element['#property_validate'])) {
+    // Validates required properties.
+    foreach ($element['#property_validate'] as $property => $callbacks) {
+      foreach ($callbacks as $callback) {
+        if (!isset($element[$property]) || !call_user_func($callback, $element)) {
+          trigger_error(t("'@type' element in form '@form_id' has a non-valid '@property' property in @parents.", array(
+            '@type' => $element['#type'],
+            '@form_id' => $form_id,
+            '@property' => $property,
+            '@parents' => '$form[\'' . implode('\'][\'', $element['#parents']) . '\']',
+          )), E_USER_ERROR);
+        }
+      }
+    }
+  }
+
   // We start off assuming all form elements are in the correct order.
   $element['#sorted'] = TRUE;
 
@@ -3362,6 +3379,19 @@ function form_pre_render_actions_dropbutton(array $element) {
 }
 
 /**
+ * Validates the title property of a form component that requires it.
+ *
+ * @param array $element
+ *   The element definition to validate #title for.
+ *
+ * @return bool
+ */
+function form_element_validate_title(&$element) {
+  // Ensures that $title is a string that does not only contain whitespace.
+  return strlen(trim($element['#title'])) !== 0;
+}
+
+/**
  * #process callback for #pattern form element property.
  *
  * @param $element
@@ -3588,6 +3618,9 @@ function form_process_tableselect($element) {
             '#parents' => $element['#parents'],
             '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
             '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
+            '#property_validate' => array(
+              '#title' => array(),
+            ),
           );
         }
         if (isset($element['#options'][$key]['#weight'])) {
@@ -4011,6 +4044,16 @@ function form_process_vertical_tabs($element, &$form_state) {
     '#parents' => $element['#parents'],
   );
 
+  // Details within a vertical tab do not require a title.
+  $details_validation = element_info_property('details', '#property_validate');
+  if (isset($details_validation['#title'])) {
+    $key = array_search('form_element_validate_title', $details_validation['#title']);
+    if ($key !== FALSE) {
+      unset($details_validation['#title'][$key]);
+    }
+  }
+  $element['group']['#property_validate'] = $details_validation;
+
   // Add an invisible label for accessibility.
   if (!isset($element['#title'])) {
     $element['#title'] = t('Vertical Tabs');
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 8e4b66e..049e7ba 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2464,6 +2464,7 @@ function _install_configure_form($form, &$form_state, &$install_state) {
   );
   $form['update_notifications']['update_status_module'] = array(
     '#type' => 'checkboxes',
+    '#title' => t('Update notifications'),
     '#options' => array(
       1 => t('Check for updates automatically'),
       2 => t('Receive e-mail notifications'),
diff --git a/core/modules/action/lib/Drupal/action/ActionFormControllerBase.php b/core/modules/action/lib/Drupal/action/ActionFormControllerBase.php
index 7c0e86d..f3f8749 100644
--- a/core/modules/action/lib/Drupal/action/ActionFormControllerBase.php
+++ b/core/modules/action/lib/Drupal/action/ActionFormControllerBase.php
@@ -72,7 +72,6 @@ public function form(array $form, array &$form_state) {
 
     $form['id'] = array(
       '#type' => 'machine_name',
-      '#title' => t('Machine name'),
       '#default_value' => $this->entity->id(),
       '#disabled' => !$this->entity->isNew(),
       '#maxlength' => 64,
diff --git a/core/modules/block/lib/Drupal/block/BlockFormController.php b/core/modules/block/lib/Drupal/block/BlockFormController.php
index c2f71ac..0e31a6d 100644
--- a/core/modules/block/lib/Drupal/block/BlockFormController.php
+++ b/core/modules/block/lib/Drupal/block/BlockFormController.php
@@ -74,7 +74,6 @@ public function form(array $form, array &$form_state) {
 
     $form['machine_name'] = array(
       '#type' => 'machine_name',
-      '#title' => t('Machine name'),
       '#maxlength' => 64,
       '#description' => t('A unique name for this block instance. Must be alpha-numeric and underscore separated.'),
       '#default_value' => !$entity->isNew() ? $entity->id() : $machine_default,
diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc
index 611537b..89d661d 100644
--- a/core/modules/book/book.admin.inc
+++ b/core/modules/book/book.admin.inc
@@ -160,6 +160,8 @@ function _book_admin_table_tree($tree, &$form) {
       'depth' => array('#type' => 'value', '#value' => $data['link']['depth']),
       'href' => array('#type' => 'value', '#value' => $data['link']['href']),
       'title' => array(
+        '#title' => t('Title'),
+        '#title_display' => 'invisible',
         '#type' => 'textfield',
         '#default_value' => $data['link']['link_title'],
         '#maxlength' => 255,
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index 4360918..0d7f302 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -119,6 +119,7 @@ function comment_admin_overview($form, &$form_state, $arg) {
       '#account' => comment_prepare_author($comment),
     );
     $options[$comment->id()] = array(
+      'title' => array('data' => array('#title' => $comment->subject->value ?: $comment->id())),
       'subject' => array(
         'data' => array(
           '#type' => 'link',
diff --git a/core/modules/config/lib/Drupal/config/Form/ConfigImportForm.php b/core/modules/config/lib/Drupal/config/Form/ConfigImportForm.php
index 1906abb..559d9bb 100644
--- a/core/modules/config/lib/Drupal/config/Form/ConfigImportForm.php
+++ b/core/modules/config/lib/Drupal/config/Form/ConfigImportForm.php
@@ -17,9 +17,10 @@ public function buildForm(array $form, array &$form_state) {
     );
     $form['import_tarball'] = array(
       '#type' => 'file',
-      '#value' => t('Select your configuration export file'),
+      '#title' => t('Select your configuration export file'),
       '#description' => t('This form will redirect you to the import configuration screen.'),
     );
+
     $form['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Upload'),
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index 97cbfa9..74a83a8 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -89,6 +89,7 @@ function _content_translation_form_language_content_settings_form_alter(array &$
         if ($fields) {
           $form['settings'][$entity_type][$bundle]['translatable'] = array(
             '#type' => 'checkbox',
+            '#title' => t($bundle),
             '#default_value' => content_translation_enabled($entity_type, $bundle),
           );
 
@@ -99,6 +100,7 @@ function _content_translation_form_language_content_settings_form_alter(array &$
             $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array(
               '#label' => $instance['label'],
               '#type' => 'checkbox',
+              '#title' => $instance['label'],
               '#default_value' => $field['translatable'],
             );
             $column_element = content_translation_field_sync_widget($field, $instance);
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
index 3374ddf..473d978 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/ContentTranslationController.php
@@ -155,6 +155,8 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
         '#weight' => -100,
         '#multilingual' => TRUE,
         'source' => array(
+          '#title' => t('Select source language'),
+          '#title_display' => 'invisible',
           '#type' => 'select',
           '#default_value' => $source_langcode,
           '#options' => array(),
diff --git a/core/modules/editor/tests/modules/lib/Drupal/editor_test/Plugin/Editor/UnicornEditor.php b/core/modules/editor/tests/modules/lib/Drupal/editor_test/Plugin/Editor/UnicornEditor.php
index ba260f2..b679139 100644
--- a/core/modules/editor/tests/modules/lib/Drupal/editor_test/Plugin/Editor/UnicornEditor.php
+++ b/core/modules/editor/tests/modules/lib/Drupal/editor_test/Plugin/Editor/UnicornEditor.php
@@ -34,7 +34,11 @@ function getDefaultSettings() {
    * Implements \Drupal\editor\Plugin\EditPluginInterface::settingsForm().
    */
   function settingsForm(array $form, array &$form_state, EditorEntity $editor) {
-    $form['foo'] = array('#type' => 'textfield', '#default_value' => 'bar');
+    $form['foo'] = array(
+      '#title' => t('Foo'),
+      '#type' => 'textfield',
+      '#default_value' => 'bar',
+    );
     return $form;
   }
 
diff --git a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php
index 6f638b7..3208e88 100644
--- a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php
+++ b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeFormBase.php
@@ -82,7 +82,6 @@ public function form(array $form, array &$form_state) {
 
     $form['id'] = array(
       '#type' => 'machine_name',
-      '#title' => t('Machine-readable name'),
       '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'),
       '#disabled' => !$this->entity->isNew(),
       '#default_value' => $this->entity->id(),
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
index 7c7a343..ae7d05f 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
@@ -181,10 +181,21 @@ protected function formMultipleElements(EntityInterface $entity, FieldInterface
     for ($delta = 0; $delta <= $max; $delta++) {
       // For multiple fields, title and description are handled by the wrapping
       // table.
-      $element = array(
-        '#title' => $is_multiple ? '' : $title,
-        '#description' => $is_multiple ? '' : $description,
-      );
+      if ($is_multiple) {
+        $element = array(
+          '#title' => '',
+          '#description' => '',
+          '#property_validate' => array(
+            '#title' => array(),
+          ),
+        );
+      }
+      else {
+        $element = array(
+          '#title' => $title,
+          '#description' => $description,
+        );
+      }
       $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
 
       if ($element) {
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 979419e..8fe508b 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -570,12 +570,18 @@ function language_negotiation_configure_browser_form($form, &$form_state) {
         '#default_value' => $browser_langcode,
         '#size' => 20,
         '#required' => TRUE,
+        '#property_validate' => array(
+          '#title' => array(),
+        ),
       ),
       'drupal_langcode' => array(
         '#type' => 'select',
         '#options' => $language_options,
         '#default_value' => $drupal_langcode,
         '#required' => TRUE,
+        '#property_validate' => array(
+          '#title' => array(),
+        ),
       ),
     );
   }
diff --git a/core/modules/language/tests/language_elements_test/language_elements_test.module b/core/modules/language/tests/language_elements_test/language_elements_test.module
index 6030e4c..14d8927 100644
--- a/core/modules/language/tests/language_elements_test/language_elements_test.module
+++ b/core/modules/language/tests/language_elements_test/language_elements_test.module
@@ -54,6 +54,7 @@ function language_elements_configuration_element() {
  */
 function language_elements_configuration_element_test() {
   $form['langcode'] = array(
+    '#title' => t('Language select'),
     '#type' => 'language_select',
     '#default_value' => language_get_default_langcode('custom_type', 'some_bundle'),
   );
diff --git a/core/modules/locale/css/locale.admin.css b/core/modules/locale/css/locale.admin.css
index c1e05e9..5d7b032 100644
--- a/core/modules/locale/css/locale.admin.css
+++ b/core/modules/locale/css/locale.admin.css
@@ -85,9 +85,10 @@
   background: transparent url(../../../misc/menu-expanded.png) left .6em no-repeat;
 }
 
-#locale-translation-status-form label {
+#locale-translation-status-form .label {
   color: #1d1d1d;
   font-size: 1.15em;
+  font-weight: bold;
 }
 #locale-translation-status-form .description {
   cursor: pointer;
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
index 9f55abc..d6fb45f 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUpdateTest.php
@@ -167,7 +167,7 @@ function testUpdateImportSourceRemote() {
     $this->drupalGet('admin/reports/translations/check');
 
     // Check the status on the Available translation status page.
-    $this->assertRaw('<label for="edit-langcodes-de" class="language-name">German</label>', 'German language found');
+    $this->assertRaw('<label class="visually-hidden" for="edit-langcodes-de">Update German</label>', 'German language found');
     $this->assertText('Updates for: Contributed module one, Contributed module two, Custom module one, Locale test', 'Updates found');
     $this->assertText('Contributed module one (' . format_date($this->timestamp_now, 'html_date') . ')', 'Updates for Contrib module one');
     $this->assertText('Contributed module two (' . format_date($this->timestamp_new, 'html_date') . ')', 'Updates for Contrib module two');
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index 83777b6..db0d371 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -5,6 +5,7 @@
  * Interface translation summary, editing and deletion user interfaces.
  */
 
+use Drupal\Component\Utility\String;
 use Drupal\Core\Language\Language;
 use Drupal\locale\SourceString;
 use Drupal\locale\TranslationString;
@@ -520,13 +521,22 @@ function locale_translation_status_form($form, &$form_state) {
 
     // Build data options for the select table.
     foreach($updates as $langcode => $update) {
+      $title = String::checkPlain($languages[$langcode]->name);
       $options[$langcode] = array(
-        'title' => check_plain($languages[$langcode]->name),
-        'status' => array('class' => array('description', 'expand', 'priority-low'), 'data' => theme('locale_translation_update_info', $update)),
+        'title' => array(
+          'class' => array('label'),
+          'data' => array('#title' => $title, '#markup' => $title),
+        ),
+        'status' => array(
+          'class' => array('description', 'expand', 'priority-low'),
+          'data' => theme('locale_translation_update_info', $update),
+        ),
       );
     }
     // Sort the table data on language name.
-    uasort($options, 'drupal_sort_title');
+    uasort($options, function ($a, $b) {
+      return strcasecmp($a['title']['data']['#title'], $b['title']['data']['#title']);
+    });
   }
 
   $last_checked = Drupal::state()->get('locale.translation_last_checked');
@@ -633,13 +643,6 @@ function locale_translation_status_form_submit($form, &$form_state) {
  * translation files could not be found.
  */
 function locale_translation_language_table($form_element) {
-  // Add labels to Language names.
-  foreach ($form_element['#options'] as $langcode => $option) {
-    $id = $form_element[$langcode]['#id'];
-    $title = $option['title'];
-    $form_element['#options'][$langcode]['title'] = '<label for="' . $form_element[$langcode]['#id'] . '" class="language-name">' . $title . '</label>';
-  }
-
   // Remove checkboxes of languages without updates.
   if ($form_element['#not_found']) {
     foreach ($form_element['#not_found'] as $langcode) {
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php b/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
index bf71eb2..b9d2a9c 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Condition/NodeType.php
@@ -39,6 +39,7 @@ public function buildForm(array $form, array &$form_state) {
       $options[$type->type] = $type->name;
     }
     $form['bundles'] = array(
+      '#title' => t('Node types'),
       '#type' => 'checkboxes',
       '#options' => $options,
       '#required' => TRUE,
diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php b/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
index 2020486..e48d38b 100644
--- a/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
+++ b/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
@@ -95,11 +95,15 @@ public function buildOptionsForm(&$form, &$form_state) {
           '#markup' => $id,
         );
         $form['field_options'][$id]['alias'] = array(
+          '#title' => t('Alias for @id', array('@id' => $id)),
+          '#title_display' => 'invisible',
           '#type' => 'textfield',
           '#default_value' => isset($options[$id]['alias']) ? $options[$id]['alias'] : '',
           '#element_validate' => array(array($this, 'validateAliasName')),
         );
         $form['field_options'][$id]['raw_output'] = array(
+          '#title' => t('Raw output for @id', array('@id' => $id)),
+          '#title_display' => 'invisible',
           '#type' => 'checkbox',
           '#default_value' => isset($options[$id]['raw_output']) ? $options[$id]['raw_output'] : '',
         );
diff --git a/core/modules/system/lib/Drupal/system/Form/CronForm.php b/core/modules/system/lib/Drupal/system/Form/CronForm.php
index 31c599b..e805ec9 100644
--- a/core/modules/system/lib/Drupal/system/Form/CronForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/CronForm.php
@@ -84,6 +84,7 @@ public function buildForm(array $form, array &$form_state) {
     );
 
     $form['cron'] = array(
+      '#title' => t('Cron settings'),
       '#type' => 'details',
     );
     $form['cron']['cron_safe_threshold'] = array(
diff --git a/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php b/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php
index e04a610..2205942 100644
--- a/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php
+++ b/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php
@@ -125,7 +125,6 @@ public function form(array $form, array &$form_state) {
 
     $form['id'] = array(
       '#type' => 'machine_name',
-      '#title' => t('Machine-readable name'),
       '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'),
       '#disabled' => !$this->entity->isNew(),
       '#default_value' => $this->entity->id(),
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index bd58f93..7fc7859 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -326,6 +326,9 @@ function system_element_info() {
     '#autocomplete_path' => FALSE,
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#pre_render' => array('form_pre_render_textfield'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -336,6 +339,9 @@ function system_element_info() {
     '#autocomplete_path' => FALSE,
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#pre_render' => array('form_pre_render_tel'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__tel',
     '#theme_wrappers' => array('form_element'),
   );
@@ -348,6 +354,9 @@ function system_element_info() {
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#element_validate' => array('form_validate_email'),
     '#pre_render' => array('form_pre_render_email'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__email',
     '#theme_wrappers' => array('form_element'),
   );
@@ -359,6 +368,9 @@ function system_element_info() {
     '#process' => array('form_process_autocomplete', 'ajax_process_form', 'form_process_pattern'),
     '#element_validate' => array('form_validate_url'),
     '#pre_render' => array('form_pre_render_url'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__url',
     '#theme_wrappers' => array('form_element'),
   );
@@ -369,6 +381,9 @@ function system_element_info() {
     '#autocomplete_path' => FALSE,
     '#process' => array('form_process_autocomplete', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_search'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__search',
     '#theme_wrappers' => array('form_element'),
   );
@@ -378,6 +393,9 @@ function system_element_info() {
     '#process' => array('ajax_process_form'),
     '#element_validate' => array('form_validate_number'),
     '#pre_render' => array('form_pre_render_number'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__number',
     '#theme_wrappers' => array('form_element'),
   );
@@ -389,6 +407,9 @@ function system_element_info() {
     '#process' => array('ajax_process_form'),
     '#element_validate' => array('form_validate_number'),
     '#pre_render' => array('form_pre_render_range'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__range',
     '#theme_wrappers' => array('form_element'),
   );
@@ -397,6 +418,9 @@ function system_element_info() {
     '#process' => array('ajax_process_form'),
     '#element_validate' => array('form_validate_color'),
     '#pre_render' => array('form_pre_render_color'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__color',
     '#theme_wrappers' => array('form_element'),
   );
@@ -410,6 +434,9 @@ function system_element_info() {
     '#process' => array('form_process_machine_name', 'form_process_autocomplete', 'ajax_process_form'),
     '#element_validate' => array('form_validate_machine_name'),
     '#pre_render' => array('form_pre_render_textfield'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -419,6 +446,9 @@ function system_element_info() {
     '#maxlength' => 128,
     '#process' => array('ajax_process_form', 'form_process_pattern'),
     '#pre_render' => array('form_pre_render_password'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__password',
     '#theme_wrappers' => array('form_element'),
   );
@@ -433,12 +463,18 @@ function system_element_info() {
     '#rows' => 5,
     '#resizable' => 'vertical',
     '#process' => array('ajax_process_form'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'textarea',
     '#theme_wrappers' => array('form_element'),
   );
   $types['radios'] = array(
     '#input' => TRUE,
     '#process' => array('form_process_radios'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme_wrappers' => array('radios'),
     '#pre_render' => array('form_pre_render_conditional_form_element'),
   );
@@ -447,6 +483,9 @@ function system_element_info() {
     '#default_value' => NULL,
     '#process' => array('ajax_process_form'),
     '#pre_render' => array('form_pre_render_radio'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__radio',
     '#theme_wrappers' => array('form_element'),
     '#title_display' => 'after',
@@ -455,6 +494,9 @@ function system_element_info() {
     '#input' => TRUE,
     '#process' => array('form_process_checkboxes'),
     '#pre_render' => array('form_pre_render_conditional_form_element'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme_wrappers' => array('checkboxes'),
   );
   $types['checkbox'] = array(
@@ -462,6 +504,9 @@ function system_element_info() {
     '#return_value' => 1,
     '#process' => array('form_process_checkbox', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_checkbox'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__checkbox',
     '#theme_wrappers' => array('form_element'),
     '#title_display' => 'after',
@@ -470,6 +515,9 @@ function system_element_info() {
     '#input' => TRUE,
     '#multiple' => FALSE,
     '#process' => array('form_process_select', 'ajax_process_form'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'select',
     '#theme_wrappers' => array('form_element'),
     '#options' => array(),
@@ -477,15 +525,24 @@ function system_element_info() {
   $types['language_select'] = array(
     '#input' => TRUE,
     '#default_value' => Language::LANGCODE_NOT_SPECIFIED,
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
   );
   $types['weight'] = array(
     '#input' => TRUE,
     '#delta' => 10,
     '#default_value' => 0,
     '#process' => array('form_process_weight', 'ajax_process_form'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
   );
   $types['date'] = array(
     '#input' => TRUE,
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'date',
     '#theme_wrappers' => array('form_element'),
   );
@@ -495,6 +552,9 @@ function system_element_info() {
     '#process' => array('form_process_file'),
     '#size' => 60,
     '#pre_render' => array('form_pre_render_file'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme' => 'input__file',
     '#theme_wrappers' => array('form_element'),
   );
@@ -540,6 +600,9 @@ function system_element_info() {
     '#value' => NULL,
     '#process' => array('form_process_group', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_group'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme_wrappers' => array('fieldset'),
   );
   $types['details'] = array(
@@ -547,6 +610,9 @@ function system_element_info() {
     '#value' => NULL,
     '#process' => array('form_process_group', 'ajax_process_form'),
     '#pre_render' => array('form_pre_render_details', 'form_pre_render_group'),
+    '#property_validate' => array(
+      '#title' => array('form_element_validate_title'),
+    ),
     '#theme_wrappers' => array('details'),
   );
   $types['vertical_tabs'] = array(
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
index 291f7bb..175d593 100644
--- a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
+++ b/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
@@ -49,6 +49,7 @@ function ajax_forms_test_simple_form($form, &$form_state) {
 
   $form = array();
   $form['select'] = array(
+    '#title' => t('Color'),
     '#type' => 'select',
     '#options' => array(
       'red' => 'red',
@@ -83,6 +84,7 @@ function ajax_forms_test_simple_form($form, &$form_state) {
   foreach ($invalid_callbacks as $key => $value) {
     $form['select_' . $key . '_callback'] = array(
       '#type' => 'select',
+      '#title' => t('Test %key callbacks', array('%key' => $key)),
       '#options' => array('red' => 'red'),
       '#ajax' => array('callback' => $value),
     );
@@ -542,6 +544,7 @@ function ajax_forms_test_lazy_load_form($form, &$form_state) {
     'data' => array('test' => 'currentPathUpdate'),
   );
   $form['add_files'] = array(
+    '#title' => t('Add files'),
     '#type' => 'checkbox',
     '#default_value' => FALSE,
   );
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index 2c1bee2..7660c73 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -312,6 +312,7 @@ function _batch_test_nested_drupal_form_submit_callback($value) {
  */
 function batch_test_mock_form($form, $form_state) {
   $form['test_value'] = array(
+    '#title' => t('Test value'),
     '#type' => 'textfield',
   );
   $form['submit'] = array(
diff --git a/core/modules/system/tests/modules/database_test/database_test.module b/core/modules/system/tests/modules/database_test/database_test.module
index b390004..518e3aa 100644
--- a/core/modules/system/tests/modules/database_test/database_test.module
+++ b/core/modules/system/tests/modules/database_test/database_test.module
@@ -1,5 +1,6 @@
 <?php
 
+use Drupal\Component\Utility\String;
 use Drupal\Core\Database\Query\AlterableInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
@@ -233,6 +234,7 @@ function database_test_theme_tablesort($form, &$form_state) {
 
   foreach (user_load_multiple($uids) as $account) {
     $options[$account->id()] = array(
+      'title' => array('data' => array('#title' => String::checkPlain($account->getUsername()))),
       'username' => check_plain($account->getUsername()),
       'status' =>  $account->isActive() ? t('active') : t('blocked'),
     );
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index fa16bf9..a6af0cd 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -558,6 +558,9 @@ function form_test_validate_required_form_no_title($form, &$form_state) {
   $form['textfield'] = array(
     '#type' => 'textfield',
     '#required' => TRUE,
+    '#property_validate' => array(
+      '#title' => array(),
+    ),
   );
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => 'Submit');
@@ -701,6 +704,7 @@ function _form_test_tableselect_get_data() {
   );
 
   $options['row1'] = array(
+    'title' => array('data' => array('#title' => t('row1'))),
     'one' => 'row1col1',
     'two' => t('row1col2'),
     'three' => t('row1col3'),
@@ -708,6 +712,7 @@ function _form_test_tableselect_get_data() {
   );
 
   $options['row2'] = array(
+    'title' => array('data' => array('#title' => t('row2'))),
     'one' => 'row2col1',
     'two' => t('row2col2'),
     'three' => t('row2col3'),
@@ -715,6 +720,7 @@ function _form_test_tableselect_get_data() {
   );
 
   $options['row3'] = array(
+    'title' => array('data' => array('#title' => t('row3'))),
     'one' => 'row3col1',
     'two' => t('row3col2'),
     'three' => t('row3col3'),
@@ -1017,6 +1023,9 @@ function form_label_test_form() {
     // and required marker.
     '#title' => '',
     '#required' => TRUE,
+    '#property_validate' => array(
+      '#title' => array(),
+    ),
   );
   $form['form_textfield_test_title'] = array(
     '#type' => 'textfield',
@@ -1039,6 +1048,9 @@ function form_label_test_form() {
   // Textfield test for title set not to display.
   $form['form_textfield_test_title_no_show'] = array(
     '#type' => 'textfield',
+    '#property_validate' => array(
+      '#title' => array(),
+    ),
   );
   // Checkboxes & radios with title as attribute.
   $form['form_checkboxes_title_attribute'] = array(
@@ -1338,25 +1350,30 @@ function form_test_language_select() {
   $form['#submit'] = array('_form_test_submit_values_json');
 
   $form['languages_all'] = array(
+    '#title' => t('Languages: All'),
     '#type' => 'language_select',
     '#languages' => Language::STATE_ALL,
     '#default_value' => 'xx',
   );
   $form['languages_configurable'] = array(
+    '#title' => t('Languages: Configurable'),
     '#type' => 'language_select',
     '#languages' => Language::STATE_CONFIGURABLE,
     '#default_value' => 'en',
   );
   $form['languages_locked'] = array(
+    '#title' => t('Languages: Locked'),
     '#type' => 'language_select',
     '#languages' => Language::STATE_LOCKED,
   );
   $form['languages_config_and_locked'] = array(
+    '#title' => t('Languages: Configurable and locked'),
     '#type' => 'language_select',
     '#languages' => Language::STATE_CONFIGURABLE | Language::STATE_LOCKED,
     '#default_value' => 'dummy_value',
   );
   $form['language_custom_options'] = array(
+    '#title' => t('Languages: Custom'),
     '#type' => 'language_select',
     '#languages' => Language::STATE_CONFIGURABLE | Language::STATE_LOCKED,
     '#options' => array('opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option'),
@@ -1907,6 +1924,7 @@ function _form_test_input_forgery($form, &$form_state) {
   // For testing that a user can't submit a value not matching one of the
   // allowed options.
   $form['checkboxes'] = array(
+    '#title' => t('Checkboxes'),
     '#type' => 'checkboxes',
     '#options' => array(
       'one' => 'One',
@@ -2050,6 +2068,7 @@ function form_test_programmatic_form($form, &$form_state) {
   );
 
   $form['checkboxes'] = array(
+    '#title' => t('Checkboxes'),
     '#type' => 'checkboxes',
     '#options' => array(
       1 => 'First checkbox',
@@ -2296,6 +2315,7 @@ function form_test_load_include_custom($form, &$form_state) {
 
 function form_test_checkbox_type_juggling($form, $form_state, $default_value, $return_value) {
   $form['checkbox'] = array(
+    '#title' => t('Checkbox'),
     '#type' => 'checkbox',
     '#return_value' => $return_value,
     '#default_value' => $default_value,
@@ -2305,15 +2325,18 @@ function form_test_checkbox_type_juggling($form, $form_state, $default_value, $r
 
 function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) {
   $form['checkbox_off'] = array(
+    '#title' => t('Checkbox off'),
     '#type' => 'checkboxes',
     '#options' => array('foo', 'bar', 'baz'),
   );
   $form['checkbox_zero_default'] = array(
+    '#title' => t('Zero default'),
     '#type' => 'checkboxes',
     '#options' => array('foo', 'bar', 'baz'),
     '#default_value' => array(0),
   );
   $form['checkbox_string_zero_default'] = array(
+    '#title' => t('Zero default (string)'),
     '#type' => 'checkboxes',
     '#options' => array('foo', 'bar', 'baz'),
     '#default_value' => array('0'),
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index 9e9d73a..ea31026 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -162,6 +162,11 @@ function update_manager_update_form($form, $form_state = array(), $context) {
         continue 2;
     }
 
+    // Use the project title for the tableselect checkboxes.
+    $entry['title'] = array('data' => array(
+      '#title' => $entry['title'],
+      '#markup' => $entry['title'],
+    ));
     $entry['#attributes'] = array('class' => array('update-' . $type));
 
     // Drupal core needs to be upgraded manually.
diff --git a/core/modules/user/lib/Drupal/user/Form/UserPermissionsForm.php b/core/modules/user/lib/Drupal/user/Form/UserPermissionsForm.php
index a78eedf..6f53601 100644
--- a/core/modules/user/lib/Drupal/user/Form/UserPermissionsForm.php
+++ b/core/modules/user/lib/Drupal/user/Form/UserPermissionsForm.php
@@ -140,7 +140,7 @@ public function buildForm(array $form, array &$form_state) {
             'restrict access' => FALSE,
             'warning' => !empty($perm_item['restrict access']) ? t('Warning: Give to trusted roles only; this permission has security implications.') : '',
           );
-          $options[$perm] = '';
+          $options[$perm] = $perm_item['title'];
           $user_permission_description = array(
             '#theme' => 'user_permission_description',
             '#permission_item' => $perm_item,
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 4caec43..fddc393 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -4,6 +4,7 @@
  * @file
  * Admin page callback file for the user module.
  */
+use Drupal\Component\Utility\String;
 
 /**
  * Page callback: User administration page.
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/area/Text.php b/core/modules/views/lib/Drupal/views/Plugin/views/area/Text.php
index 645e10d..e0b7715 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/area/Text.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/area/Text.php
@@ -35,6 +35,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
     $form['content'] = array(
+      '#title' => t('Content'),
       '#type' => 'text_format',
       '#default_value' => $this->options['content'],
       '#rows' => 6,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/area/TextCustom.php b/core/modules/views/lib/Drupal/views/Plugin/views/area/TextCustom.php
index 2b07806..dac9815 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/area/TextCustom.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/area/TextCustom.php
@@ -34,6 +34,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
     $form['content'] = array(
+      '#title' => t('Content'),
       '#type' => 'textarea',
       '#default_value' => $this->options['content'],
       '#rows' => 6,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php
index 862a847..0b0f992 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php
@@ -184,6 +184,8 @@ public function buildOptionsForm(&$form, &$form_state) {
       '#markup' => '<div class="clearfix"></div>',
     );
     $form['default_action'] = array(
+      '#title' => t('Default actions'),
+      '#title_display' => 'invisible',
       '#type' => 'radios',
       '#process' => array(array($this, 'processContainerRadios')),
       '#default_value' => $this->options['default_action'],
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Attachment.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Attachment.php
index a36f441..0b7e121 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Attachment.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Attachment.php
@@ -185,6 +185,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       case 'attachment_position':
         $form['#title'] .= t('Position');
         $form['attachment_position'] = array(
+          '#title' => t('Position'),
           '#type' => 'radios',
           '#description' => t('Attach before or after the parent display?'),
           '#options' => $this->attachmentPositions(),
@@ -200,6 +201,7 @@ public function buildOptionsForm(&$form, &$form_state) {
           }
         }
         $form['displays'] = array(
+          '#title' => t('Displays'),
           '#type' => 'checkboxes',
           '#description' => t('Select which display or displays this should attach to.'),
           '#options' => $displays,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index 388d599..c2c9ec1 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -1411,6 +1411,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       case 'title':
         $form['#title'] .= t('The title of this view');
         $form['title'] = array(
+          '#title' => t('Title'),
           '#type' => 'textfield',
           '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'),
           '#default_value' => $this->getOption('title'),
@@ -1500,6 +1501,8 @@ public function buildOptionsForm(&$form, &$form_state) {
 
         $access = $this->getOption('access');
         $form['access']['type'] =  array(
+          '#title' => t('Access'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('access', $this->getType(), array($this->view->storage->get('base_table'))),
           '#default_value' => $access['type'],
@@ -1535,6 +1538,8 @@ public function buildOptionsForm(&$form, &$form_state) {
 
         $cache = $this->getOption('cache');
         $form['cache']['type'] =  array(
+          '#title' => t('Caching'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('cache', $this->getType(), array($this->view->storage->get('base_table'))),
           '#default_value' => $cache['type'],
@@ -1626,6 +1631,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         $form['#title'] .= t('How should this view be styled');
         $style_plugin = $this->getPlugin('style');
         $form['style'] =  array(
+          '#title' => t('Style'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('style', $this->getType(), array($this->view->storage->get('base_table'))),
           '#default_value' => $style_plugin->definition['id'],
@@ -1668,6 +1675,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         $form['#title'] .= t('How should each row in this view be styled');
         $row_plugin_instance = $this->getPlugin('row');
         $form['row'] =  array(
+          '#title' => t('Row'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('row', $this->getType(), array($this->view->storage->get('base_table'))),
           '#default_value' => $row_plugin_instance->definition['id'],
@@ -1692,6 +1701,7 @@ public function buildOptionsForm(&$form, &$form_state) {
         $options['custom_url'] = t('Custom URL');
         if (count($options)) {
           $form['link_display'] = array(
+            '#title' => t('Custom URL'),
             '#type' => 'radios',
             '#options' => $options,
             '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
@@ -1859,6 +1869,8 @@ public function buildOptionsForm(&$form, &$form_state) {
           '#suffix' => '</div>',
         );
         $form['box']['theme'] = array(
+          '#title' => t('Theme'),
+          '#title_display' => 'invisible',
           '#type' => 'select',
           '#options' => $options,
           '#default_value' => $this->theme,
@@ -1987,6 +1999,8 @@ public function buildOptionsForm(&$form, &$form_state) {
 
         $exposed_form = $this->getOption('exposed_form');
         $form['exposed_form']['type'] =  array(
+          '#title' => t('Exposed form'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('exposed_form', $this->getType(), array($this->view->storage->get('base_table'))),
           '#default_value' => $exposed_form['type'],
@@ -2021,6 +2035,8 @@ public function buildOptionsForm(&$form, &$form_state) {
 
         $pager = $this->getOption('pager');
         $form['pager']['type'] =  array(
+          '#title' => t('Pager'),
+          '#title_display' => 'invisible',
           '#type' => 'radios',
           '#options' => views_fetch_plugin_names('pager', !$this->usesPager() ? 'basic' : NULL, array($this->view->storage->get('base_table'))),
           '#default_value' => $pager['type'],
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
index 02af7ce..504c866 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
@@ -218,6 +218,7 @@ public function buildOptionsForm(&$form, &$form_state) {
           }
         }
         $form['displays'] = array(
+          '#title' => t('Displays'),
           '#type' => 'checkboxes',
           '#description' => t('The feed icon will be available only to the selected displays.'),
           '#options' => $displays,
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
index 57691f1..79795d2 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
@@ -305,6 +305,7 @@ public function buildOptionsForm(&$form, &$form_state) {
         $form['#title'] .= t('The menu path or URL of this view');
         $form['path'] = array(
           '#type' => 'textfield',
+          '#title' => t('Path'),
           '#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
           '#default_value' => $this->getOption('path'),
           '#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)),
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
index 316f980..b9f06b5 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\views\Plugin\views\filter;
 
 use Drupal\views\Plugin\views\HandlerBase;
+use Drupal\Component\Utility\String;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\Component\Annotation\Plugin;
 use Drupal\views\ViewExecutable;
@@ -745,6 +746,7 @@ public function groupForm(&$form, &$form_state) {
       $value = $this->options['group_info']['identifier'];
 
       $form[$value] = array(
+        '#title' => String::checkPlain($this->options['group_info']['label']),
         '#type' => $this->options['group_info']['widget'],
         '#default_value' => $this->group_info,
         '#options' => $groups,
@@ -785,10 +787,6 @@ public function buildExposedForm(&$form, &$form_state) {
       $this->operatorForm($form, $form_state);
       $form[$operator] = $form['operator'];
 
-      if (isset($form[$operator]['#title'])) {
-        unset($form[$operator]['#title']);
-      }
-
       $this->exposedTranslate($form[$operator], 'operator');
 
       unset($form['operator']);
@@ -798,11 +796,11 @@ public function buildExposedForm(&$form, &$form_state) {
     if (!empty($this->options['expose']['identifier'])) {
       $value = $this->options['expose']['identifier'];
       $this->valueForm($form, $form_state);
-      $form[$value] = $form['value'];
-
-      if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
-        unset($form[$value]['#title']);
+      // If no title was specified, prevent validation errors.
+      if (!isset($form['value']['#title']) || trim($form['value']['#title']) == '') {
+        $form['value']['#property_validate']['#title'] = array();
       }
+      $form[$value] = $form['value'];
 
       $this->exposedTranslate($form[$value], 'value');
 
@@ -954,12 +952,13 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
       // In each row, we have to display the operator form and the value from
       // $row acts as a fake form to render each widget in a row.
       $row = array();
-      $groups[$item_id] = '';
+      $groups[$item_id] = t('Grouping @id', array('@id' => $item_id));
       $this->operatorForm($row, $form_state);
       // Force the operator form to be a select box. Some handlers uses
       // radios and they occupy a lot of space in a table row.
       $row['operator']['#type'] = 'select';
       $row['operator']['#title'] = '';
+      $row['operator']['#property_validate']['#title'] = array();
       $this->valueForm($row, $form_state);
 
       // Fix the dependencies to update value forms when operators
@@ -985,7 +984,7 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
             unset($row['value'][$children]['#states']['visible'][$key]);
           }
 
-          $row['value'][$children]['#title'] = '';
+          $row['value'][$children]['#property_validate']['#title'] = array();
 
           if (!empty($this->options['group_info']['group_items'][$item_id]['value'][$children])) {
             $row['value'][$children]['#default_value'] = $this->options['group_info']['group_items'][$item_id]['value'][$children];
@@ -1012,6 +1011,8 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
       // Per item group, we have a title that identifies it.
       $form['group_info']['group_items'][$item_id] = array(
         'title' => array(
+          '#title' => t('Label'),
+          '#title_display' => 'invisible',
           '#type' => 'textfield',
           '#size' => 20,
           '#default_value' => $default_title,
@@ -1019,12 +1020,16 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
         'operator' => $row['operator'],
         'value' => $row['value'],
         'remove' => array(
+          '#title' => t('Remove'),
+          '#title_display' => 'invisible',
           '#type' => 'checkbox',
           '#id' => 'views-removed-' . $item_id,
           '#attributes' => array('class' => array('views-remove-checkbox')),
           '#default_value' => 0,
         ),
         'weight' => array(
+          '#title' => t('Weight'),
+          '#title_display' => 'invisible',
           '#type' => 'weight',
           '#delta' => 10,
           '#default_value' => $default_weight++,
@@ -1040,7 +1045,10 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
       '#required' => TRUE,
       '#attributes' => array(
         'class' => array('default-radios'),
-      )
+      ),
+      '#property_validate' => array(
+        '#title' => array(),
+      ),
     );
     // From all groups, let chose which is the default.
     $form['group_info']['default_group_multiple'] = array(
@@ -1049,7 +1057,10 @@ protected function buildExposedFiltersGroupForm(&$form, &$form_state) {
       '#default_value' => $this->options['group_info']['default_group_multiple'],
       '#attributes' => array(
         'class' => array('default-checkboxes'),
-      )
+      ),
+      '#property_validate' => array(
+        '#title' => array(),
+      ),
     );
 
     $form['group_info']['add_group'] = array(
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/SortPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/SortPluginBase.php
index ddd022c..d9b6326 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/SortPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/SortPluginBase.php
@@ -164,6 +164,7 @@ protected function showSortForm(&$form, &$form_state) {
     $options = $this->sortOptions();
     if (!empty($options)) {
       $form['order'] = array(
+        '#title' => t('Order'),
         '#type' => 'radios',
         '#options' => $options,
         '#default_value' => $this->options['order'],
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php
index 178af9f..d8d49f2 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Table.php
@@ -301,12 +301,16 @@ public function buildOptionsForm(&$form, &$form_state) {
       $column_selector = ':input[name="style_options[columns][' . $field . ']"]';
 
       $form['columns'][$field] = array(
+        '#title' => t('Columns for @field', array('@field' => $field)),
+        '#title_display' => 'invisible',
         '#type' => 'select',
         '#options' => $field_names,
         '#default_value' => $column,
       );
       if ($handlers[$field]->clickSortable()) {
         $form['info'][$field]['sortable'] = array(
+          '#title' => t('Sortable for @field', array('@field' => $field)),
+          '#title_display' => 'invisible',
           '#type' => 'checkbox',
           '#default_value' => !empty($this->options['info'][$field]['sortable']),
           '#states' => array(
@@ -316,6 +320,8 @@ public function buildOptionsForm(&$form, &$form_state) {
           ),
         );
         $form['info'][$field]['default_sort_order'] = array(
+          '#title' => t('Default sort order for @field', array('@field' => $field)),
+          '#title_display' => 'invisible',
           '#type' => 'select',
           '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')),
           '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc',
@@ -329,6 +335,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         // Provide an ID so we can have such things.
         $radio_id = drupal_html_id('edit-default-' . $field);
         $form['default'][$field] = array(
+          '#title' => t('Default sort for @field', array('@field' => $field)),
+          '#title_display' => 'invisible',
           '#type' => 'radio',
           '#return_value' => $field,
           '#parents' => array('style_options', 'default'),
@@ -344,6 +352,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         );
       }
       $form['info'][$field]['align'] = array(
+        '#title' => t('Alignment for @field', array('@field' => $field)),
+        '#title_display' => 'invisible',
         '#type' => 'select',
         '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '',
         '#options' => array(
@@ -359,6 +369,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         ),
       );
       $form['info'][$field]['separator'] = array(
+        '#title' => t('Separator for @field', array('@field' => $field)),
+        '#title_display' => 'invisible',
         '#type' => 'textfield',
         '#size' => 10,
         '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '',
@@ -369,6 +381,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         ),
       );
       $form['info'][$field]['empty_column'] = array(
+        '#title' => t('Hide empty column for @field', array('@field' => $field)),
+        '#title_display' => 'invisible',
         '#type' => 'checkbox',
         '#default_value' => isset($this->options['info'][$field]['empty_column']) ? $this->options['info'][$field]['empty_column'] : FALSE,
         '#states' => array(
@@ -378,6 +392,8 @@ public function buildOptionsForm(&$form, &$form_state) {
         ),
       );
       $form['info'][$field]['responsive'] = array(
+        '#title' => t('Responsive setting for @field', array('@field' => $field)),
+        '#title_display' => 'invisible',
         '#type' => 'select',
         '#default_value' => isset($this->options['info'][$field]['responsive']) ? $this->options['info'][$field]['responsive'] : '',
         '#options' => array('' => t('High'), RESPONSIVE_PRIORITY_MEDIUM => t('Medium'), RESPONSIVE_PRIORITY_LOW => t('Low')),
@@ -396,6 +412,8 @@ public function buildOptionsForm(&$form, &$form_state) {
 
     // Provide a radio for no default sort
     $form['default'][-1] = array(
+      '#title' => t('No default sort'),
+      '#title_display' => 'invisible',
       '#type' => 'radio',
       '#return_value' => -1,
       '#parents' => array('style_options', 'default'),
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
index ccafc56..50cc2c7 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
@@ -211,6 +211,7 @@ public function buildForm(array $form, array &$form_state) {
 
     $form['displays']['page'] = array(
       '#type' => 'fieldset',
+      '#title' => t('Page settings'),
       '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')),
       '#tree' => TRUE,
     );
@@ -248,6 +249,7 @@ public function buildForm(array $form, array &$form_state) {
     );
     $form['displays']['page']['options']['style'] = array(
       '#type' => 'fieldset',
+      '#title' => t('Page display settings'),
       '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')),
     );
 
@@ -354,6 +356,7 @@ public function buildForm(array $form, array &$form_state) {
 
     $form['displays']['block'] = array(
       '#type' => 'fieldset',
+      '#title' => t('Block settings'),
       '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')),
       '#tree' => TRUE,
     );
@@ -385,6 +388,7 @@ public function buildForm(array $form, array &$form_state) {
     );
     $form['displays']['block']['options']['style'] = array(
       '#type' => 'fieldset',
+      '#title' => t('Block display settings'),
       '#attributes' => array('class' => array('container-inline', 'fieldset-no-legend')),
     );
 
diff --git a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display/DisplayTest.php b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display/DisplayTest.php
index 7f35daf..38fb4e5 100644
--- a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display/DisplayTest.php
+++ b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display/DisplayTest.php
@@ -81,6 +81,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       case 'test_option':
         $form['#title'] .= t('Test option');
         $form['test_option'] = array(
+          '#title' => t('Test option'),
           '#type' => 'textfield',
           '#description' => t('This is a textfield for test_option.'),
           '#default_value' => $this->getOption('test_option'),
diff --git a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display_extender/DisplayExtenderTest.php b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display_extender/DisplayExtenderTest.php
index 248526b..94df8e2 100644
--- a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display_extender/DisplayExtenderTest.php
+++ b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/display_extender/DisplayExtenderTest.php
@@ -68,6 +68,7 @@ public function buildOptionsForm(&$form, &$form_state) {
       case 'test_extender_test_option':
         $form['#title'] .= t('Test option');
         $form['test_extender_test_option'] = array(
+          '#title' => t('Test option'),
           '#type' => 'textfield',
           '#description' => t('This is a textfield for test_option.'),
           '#default_value' => $this->displayHandler->getOption('test_extender_test_option'),
diff --git a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/row/RowTest.php b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/row/RowTest.php
index 400ccc3..2677d77 100644
--- a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/row/RowTest.php
+++ b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/row/RowTest.php
@@ -51,6 +51,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
     $form['test_option'] = array(
+      '#title' => t('Test option'),
       '#type' => 'textfield',
       '#description' => t('This is a textfield for test_option.'),
       '#default_value' => $this->options['test_option'],
diff --git a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
index b6fc20a..8439a26 100644
--- a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
+++ b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
@@ -58,6 +58,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     parent::buildOptionsForm($form, $form_state);
 
     $form['test_option'] = array(
+      '#title' => t('Test option'),
       '#type' => 'textfield',
       '#description' => t('This is a textfield for test_option.'),
       '#default_value' => $this->options['test_option'],
diff --git a/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc b/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc
index e5a4277..701624b 100644
--- a/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc
+++ b/core/modules/views/tests/modules/views_test_data/views_test_data.views_execution.inc
@@ -18,7 +18,7 @@ function views_test_data_views_query_substitutions(ViewExecutable $view) {
 /**
  * Implements hook_views_form_substitutions().
  */
-function views_test_data_views_form_substitutions(ViewExecutable $view) {
+function views_test_data_views_form_substitutions() {
   Drupal::state()->set('views_hook_test_views_form_substitutions', TRUE);
 }
 
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
index e71ebff..0d1c3b1 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/Rearrange.php
@@ -101,6 +101,7 @@ public function buildForm(array $form, array &$form_state) {
         );
       }
       else {
+        $name = $id;
         $form['fields'][$id]['name'] = array('#markup' => t('Broken field @id', array('@id' => $id)));
       }
 
@@ -108,10 +109,14 @@ public function buildForm(array $form, array &$form_state) {
         '#type' => 'textfield',
         '#default_value' => ++$count,
         '#attributes' => array('class' => array('weight')),
+        '#title_display' => 'invisible',
+        '#title' => t('Weight for @title', array('@title' => $name)),
       );
 
       $form['fields'][$id]['removed'] = array(
         '#type' => 'checkbox',
+        '#title' => t('Remove @title', array('@title' => $name)),
+        '#title_display' => 'invisible',
         '#id' => 'views-removed-' . $id,
         '#attributes' => array('class' => array('views-remove-checkbox')),
         '#default_value' => 0,
@@ -119,11 +124,6 @@ public function buildForm(array $form, array &$form_state) {
       );
     }
 
-    $name = NULL;
-    if (isset($form_state['update_name'])) {
-      $name = $form_state['update_name'];
-    }
-
     $view->getStandardButtons($form, $form_state, 'views_ui_rearrange_form');
 
     return $form;
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
index c6ffdbf..d0b5556 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/RearrangeFilter.php
@@ -157,11 +157,15 @@ public function buildForm(array $form, array &$form_state) {
       $form['#group_renders'][$field['group']][] = $id;
 
       $form['filters'][$id]['weight'] = array(
+        '#title' => t('Weight for @id', array('@id' => $id)),
+        '#title_display' => 'invisible',
         '#type' => 'textfield',
         '#default_value' => ++$count,
         '#size' => 8,
       );
       $form['filters'][$id]['group'] = array(
+        '#title' => t('Group for @id', array('@id' => $id)),
+        '#title_display' => 'invisible',
         '#type' => 'select',
         '#options' => $group_options,
         '#default_value' => $field['group'],
@@ -185,6 +189,8 @@ public function buildForm(array $form, array &$form_state) {
         $form['filters'][$id]['name'] = array('#markup' => t('Broken field @id', array('@id' => $id)));
       }
       $form['filters'][$id]['removed'] = array(
+        '#title' => t('Remove @id', array('@id' => $id)),
+        '#title_display' => 'invisible',
         '#type' => 'checkbox',
         '#id' => 'views-removed-' . $id,
         '#attributes' => array('class' => array('views-remove-checkbox')),
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
index cc921ae..7915b74 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/Ajax/ReorderDisplays.php
@@ -98,6 +98,8 @@ public function buildForm(array $form, array &$form_state) {
 
       $form['displays'][$id]['removed'] = array(
         'checkbox' => array(
+          '#title' => t('Remove @id', array('@id' => $id)),
+          '#title_display' => 'invisible',
           '#type' => 'checkbox',
           '#id' => 'display-removed-' . $id,
           '#attributes' => array(
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php b/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
index bfac4e6..1397e00 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/Form/BasicSettingsForm.php
@@ -95,6 +95,7 @@ public function buildForm(array $form, array &$form_state) {
 
     $form['live_preview']['options']['ui_show_sql_query_where'] = array(
       '#type' => 'radios',
+      '#title' => t('Show SQL query'),
       '#options' => array(
         'above' => t('Above the preview'),
         'below' => t('Below the preview'),
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php
index da6e2d6..447ef37 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php
@@ -69,6 +69,7 @@ public function form(array $form, array &$form_state) {
 
     $form['name'] = array(
       '#type' => 'fieldset',
+      '#title' => t('View basic information'),
       '#attributes' => array('class' => array('fieldset-no-legend')),
     );
 
@@ -118,6 +119,7 @@ public function form(array $form, array &$form_state) {
     // properties of what the view will display.
     $form['displays']['show'] = array(
       '#type' => 'fieldset',
+      '#title' => t('View settings'),
       '#tree' => TRUE,
       '#attributes' => array('class' => array('container-inline')),
     );
