diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 80ceb75..15b5cf5 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -241,7 +241,7 @@ public function elementType($none_supported = FALSE, $default_empty = FALSE, $in
       }
     }
     if ($this->options['element_type']) {
-      return SafeMarkup::checkPlain($this->options['element_type']);
+      return $this->options['element_type'];
     }
 
     if ($default_empty) {
@@ -269,7 +269,7 @@ public function elementLabelType($none_supported = FALSE, $default_empty = FALSE
       }
     }
     if ($this->options['element_label_type']) {
-      return SafeMarkup::checkPlain($this->options['element_label_type']);
+      return $this->options['element_label_type'];
     }
 
     if ($default_empty) {
@@ -289,7 +289,7 @@ public function elementWrapperType($none_supported = FALSE, $default_empty = FAL
       }
     }
     if ($this->options['element_wrapper_type']) {
-      return SafeMarkup::checkPlain($this->options['element_wrapper_type']);
+      return $this->options['element_wrapper_type'];
     }
 
     if ($default_empty) {
diff --git a/core/modules/views/src/Tests/ViewsEscapingTest.php b/core/modules/views/src/Tests/ViewsEscapingTest.php
new file mode 100644
index 0000000..bde5fd5
--- /dev/null
+++ b/core/modules/views/src/Tests/ViewsEscapingTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Tests\ViewsEscapingTest.
+ */
+
+namespace Drupal\views\Tests;
+
+/**
+ * Tests output of Views.
+ *
+ * @group views
+ */
+class ViewsEscapingTest extends ViewTestBase {
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_page_display');
+
+
+  /**
+   * Used by WebTestBase::setup()
+   *
+   * We need theme_test for testing against test_basetheme and test_subtheme.
+   *
+   * @var array
+   *
+   * @see \Drupal\simpletest\WebTestBase::setup()
+   */
+  public static $modules = array('views', 'theme_test');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->enableViewsTestModule();
+  }
+
+  /**
+   * Tests for incorrectly escaped markup in the views-view-fields.html.twig.
+   */
+  public function testViewsViewFieldsEscaping() {
+    \Drupal::service('theme_handler')->install(array('views_test_theme'));
+
+    // Make base theme default then test for hook invocations.
+    $this->config('system.theme')
+        ->set('default', 'views_test_theme')
+        ->save();
+    $this->assertEqual($this->config('system.theme')->get('default'), 'views_test_theme');
+
+    $this->drupalGet('test_page_display_200');
+    $this->assertNoRaw('&lt;/');
+  }
+
+}
diff --git a/core/modules/views/templates/views-view-fields.html.twig b/core/modules/views/templates/views-view-fields.html.twig
index dc39897..e622fb3 100644
--- a/core/modules/views/templates/views-view-fields.html.twig
+++ b/core/modules/views/templates/views-view-fields.html.twig
@@ -11,13 +11,15 @@
  *   - class: The safe class ID to use.
  *   - handler: The Views field handler controlling this field.
  *   - inline: Whether or not the field should be inline.
- *   - inline_html: Either div or span based on the 'inline' flag.
- *   - wrapper_prefix: A complete wrapper containing the inline_html to use.
- *   - wrapper_suffix: The closing tag for the wrapper.
+ *   - wrapper_element: An HTML element for a wrapper.
+ *   - wrapper_attributes: List of attributes for wrapper element.
  *   - separator: An optional separator that may appear before a field.
  *   - label: The field's label text.
- *   - label_html: The full HTML of the label to use including configured
- *     element type.
+ *   - label_element: An HTML element for a label wrapper.
+ *   - label_attributes: List of attributes for label wrapper.
+ *   - label_suffix: Colon after the label.
+ *   - element_type: An HTML element for the field content.
+ *   - element_attributes: List of attributes for HTML element for field content.
  * - row: The raw result from the query, with all data it fetched.
  *
  * @see template_preprocess_views_view_fields()
@@ -29,13 +31,25 @@
 THIS FILE IS NOT USED AND IS HERE AS A STARTING POINT FOR CUSTOMIZATION ONLY.
 See http://api.drupal.org/api/function/theme_views_view_fields/8 for details.
 After copying this file to your theme's folder and customizing it, remove this
-comment.
-#}
-{% for field in fields %}
+HTML comment.
+{% for field in fields -%}
   {{ field.separator }}
-
-  {{ field.wrapper_prefix }}
-    {{ field.label_html }}
+  {%- if field.wrapper_element -%}
+    <{{ field.wrapper_element }}{{ field.wrapper_attributes }}>
+  {%- endif %}
+  {%- if field.label -%}
+    {%- if field.label_element -%}
+      <{{ field.label_element }}{{ field.label_attributes }}>{{ field.label }}{{ field.label_suffix }}</{{ field.label_element }}>
+    {%- else -%}
+      {{ field.label }}{{ field.label_suffix }}
+    {%- endif %}
+  {%- endif %}
+  {%- if field.element_type -%}
+    <{{ field.element_type }}{{ field.element_attributes }}>{{ field.content }}</{{ field.element_type }}>
+  {%- else -%}
     {{ field.content }}
-  {{ field.wrapper_suffix }}
-{% endfor %}
+  {%- endif %}
+  {%- if field.wrapper_element -%}
+    </{{ field.wrapper_element }}>
+  {%- endif %}
+{%- endfor %}
diff --git a/core/modules/views/tests/themes/views_test_theme/templates/views-view-fields.html.twig b/core/modules/views/tests/themes/views_test_theme/templates/views-view-fields.html.twig
new file mode 100644
index 0000000..e5297f2
--- /dev/null
+++ b/core/modules/views/tests/themes/views_test_theme/templates/views-view-fields.html.twig
@@ -0,0 +1,48 @@
+{#
+/**
+ * @file
+ * Theme override to display all the fields in a views row.
+ *
+ * Available variables:
+ * - view: The view in use.
+ * - fields: A list of fields, each one contains:
+ *   - content: The output of the field.
+ *   - raw: The raw data for the field, if it exists. This is NOT output safe.
+ *   - class: The safe class ID to use.
+ *   - handler: The Views field handler controlling this field.
+ *   - inline: Whether or not the field should be inline.
+ *   - wrapper_element: An HTML element for a wrapper.
+ *   - wrapper_attributes: List of attributes for wrapper element.
+ *   - separator: An optional separator that may appear before a field.
+ *   - label: The field's label text.
+ *   - label_element: An HTML element for a label wrapper.
+ *   - label_attributes: List of attributes for label wrapper.
+ *   - label_suffix: Colon after the label.
+ *   - element_type: An HTML element for the field content.
+ *   - element_attributes: List of attributes for HTML element for field content.
+ * - row: The raw result from the query, with all data it fetched.
+ *
+ * @see template_preprocess_views_view_fields()
+ */
+#}
+{% for field in fields -%}
+  {{ field.separator }}
+  {%- if field.wrapper_element -%}
+    <{{ field.wrapper_element }}{{ field.wrapper_attributes }}>
+  {%- endif %}
+  {%- if field.label -%}
+    {%- if field.label_element -%}
+      <{{ field.label_element }}{{ field.label_attributes }}>{{ field.label }}{{ field.label_suffix }}</{{ field.label_element }}>
+    {%- else -%}
+      {{ field.label }}{{ field.label_suffix }}
+    {%- endif %}
+  {%- endif %}
+  {%- if field.element_type -%}
+    <{{ field.element_type }}{{ field.element_attributes }}>{{ field.content }}</{{ field.element_type }}>
+  {%- else -%}
+    {{ field.content }}
+  {%- endif %}
+  {%- if field.wrapper_element -%}
+    </{{ field.wrapper_element }}>
+  {%- endif %}
+{%- endfor %}
diff --git a/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml b/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml
new file mode 100644
index 0000000..b32f40a
--- /dev/null
+++ b/core/modules/views/tests/themes/views_test_theme/views_test_theme.info.yml
@@ -0,0 +1,5 @@
+name: Views test theme
+type: theme
+description: Theme for testing Views functionality.
+version: VERSION
+core: 8.x
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 7728d89..5246ccc 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -101,18 +101,7 @@ function template_preprocess_views_view_fields(&$variables) {
         if ($classes = $object->handler->elementClasses($row->index)) {
           $attributes['class'][] = $classes;
         }
-        $attributes = new Attribute($attributes);
-
-        $pre = '<' . $object->element_type;
-        $pre .= $attributes;
-        $field_output = $pre . '>' . $field_output . '</' . $object->element_type . '>';
-      }
-
-      // Protect ourselves somewhat for backward compatibility. This will
-      // prevent old templates from producing invalid HTML when no element type
-      // is selected.
-      if (empty($object->element_type)) {
-        $object->element_type = 'span';
+        $object->element_attributes = new Attribute($attributes);
       }
 
       $object->content = $field_output;
@@ -130,16 +119,14 @@ function template_preprocess_views_view_fields(&$variables) {
       $object->class = Html::cleanCssIdentifier($id);
 
       $previous_inline = $object->inline;
-      $object->inline_html = $object->handler->elementWrapperType(TRUE, TRUE);
-      if ($object->inline_html === '' && $variables['options']['default_field_elements']) {
-        $object->inline_html = $object->inline ? 'span' : 'div';
+      // Set up field wrapper element.
+      $object->wrapper_element = $object->handler->elementWrapperType(TRUE, TRUE);
+      if ($object->wrapper_element === '' && $variables['options']['default_field_elements']) {
+        $object->wrapper_element = $object->inline ? 'span' : 'div';
       }
 
-      // Set up the wrapper HTML.
-      $object->wrapper_prefix = '';
-      $object->wrapper_suffix = '';
-
-      if ($object->inline_html) {
+      // Set up field wrapper attributes if field wrapper was set.
+      if ($object->wrapper_element) {
         $attributes = array();
         if ($object->handler->options['element_default_classes']) {
           $attributes['class'][] = 'views-field';
@@ -149,26 +136,24 @@ function template_preprocess_views_view_fields(&$variables) {
         if ($classes = $object->handler->elementWrapperClasses($row->index)) {
           $attributes['class'][] = $classes;
         }
-        $attributes = new Attribute($attributes);
-
-        $object->wrapper_prefix = '<' . $object->inline_html;
-        $object->wrapper_prefix .= $attributes;
-        $object->wrapper_prefix .= '>';
-        $object->wrapper_suffix = '</' . $object->inline_html . '>';
+        $object->wrapper_attributes = new Attribute($attributes);
       }
 
-      // Set up the label for the value and the HTML to make it easier
-      // on the template.
-      $object->label = SafeMarkup::checkPlain($view->field[$id]->label());
-      $object->label_html = '';
+      // Set up field label
+      $object->label = $view->field[$id]->label();
+
+      // Set up field label wrapper and its attributes.
       if ($object->label) {
-        $object->label_html .= $object->label;
+        // Add a colon in a label suffix.
         if ($object->handler->options['element_label_colon']) {
-          $object->label_html .= ': ';
+          $object->label_suffix = ': ';
         }
 
-        $object->elementLabelType = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']);
-        if ($object->elementLabelType) {
+        // Set up label HTML element.
+        $object->label_element = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']);
+
+        // Set up label attributes.
+        if ($object->label_element) {
           $attributes = array();
           if ($object->handler->options['element_default_classes']) {
             $attributes['class'][] = 'views-label';
@@ -179,13 +164,7 @@ function template_preprocess_views_view_fields(&$variables) {
           if ($element_label_class) {
             $attributes['class'][] = $element_label_class;
           }
-          $attributes = new Attribute($attributes);
-
-          $pre = '<' . $object->elementLabelType;
-          $pre .= $attributes;
-          $pre .= '>';
-
-          $object->label_html = $pre . $object->label_html . '</' . $object->elementLabelType . '>';
+          $object->label_attributes = new Attribute($attributes);
         }
       }
 
@@ -219,12 +198,32 @@ function theme_views_view_fields($variables) {
     if (!empty($field->separator)) {
       $output .= $field->separator;
     }
-
-    $output .= $field->wrapper_prefix;
-    $output .= $field->label_html;
+    $wrapper_element = SafeMarkup::checkPlain($field->wrapper_element);
+    if ($wrapper_element) {
+      $output .= '<' . $wrapper_element . $field->wrapper_attributes . '>';
+      if (isset($field->label_element) && !empty($field->label_element)) {
+        $label_element = SafeMarkup::checkPlain($field->label_element);
+        $output .= '<' . $label_element . $field->label_attributes . '>';
+      }
+      $output .= SafeMarkup::checkPlain($field->label);
+      if (isset($field->label_suffix) && isset($field->label_suffix)) {
+        $output .= $field->label_suffix;
+      }
+      if (isset($label_element)) {
+        $output .= '</' . $label_element . '>';
+      }
+    }
+    $element_type = SafeMarkup::checkPlain($field->element_type);
+    if ($element_type) {
+      $output .= '<' . $element_type . $field->element_attributes . '>';
+    }
     $output .= $field->content;
-
-    $output .= $field->wrapper_suffix;
+    if ($element_type) {
+      $output .= '</' . $element_type . '>';
+    }
+    if ($wrapper_element) {
+      $output .= '</' . $wrapper_element . '>';
+    }
   }
 
   return $output;
