diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 131e4f68a..5d7249dd5 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -8,6 +8,7 @@
  * customized by user themes.
  */

+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Url;
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\Crypt;
@@ -785,6 +786,9 @@ function template_preprocess_links(&$variables) {
  *     - http://dev.w3.org/html5/spec/Overview.html#alt
  *   - title: The title text is displayed when the image is hovered in some
  *     popular browsers.
+ *   - timestamp: The changed date of the image file. It busts the browser cache
+ *     if the image file has been modified by appending the date as
+ *     query string.
  *   - attributes: Associative array of attributes to be placed in the img tag.
  *   - srcset: Array of multiple URIs and sizes/multipliers.
  *   - sizes: The sizes attribute for viewport-based selection of images.
@@ -792,8 +796,18 @@ function template_preprocess_links(&$variables) {
  */
 function template_preprocess_image(&$variables) {
   if (!empty($variables['uri'])) {
-    $variables['attributes']['src'] = file_url_transform_relative(file_create_url($variables['uri']));
+    if(isset($variables['timestamp'])) {
+      $path = UrlHelper::parse($variables['uri']);
+      $query = $path['query'];
+      $query += array('timestamp' => $variables['timestamp']);
+      $file_url = file_create_url($path['path']);
+      $variables['attributes']['src'] =  $file_url . '?'. UrlHelper::buildQuery($query);
+    }
+    else {
+      $variables['attributes']['src'] = file_url_transform_relative(file_create_url($variables['uri']));
+    }
   }
+
   // Generate a srcset attribute conforming to the spec at
   // http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-srcset
   if (!empty($variables['srcset'])) {
@@ -1781,7 +1795,7 @@ function drupal_common_theme() {
       // - http://dev.w3.org/html5/spec/Overview.html#alt
       // The title attribute is optional in all cases, so it is omitted by
       // default.
-      'variables' => ['uri' => NULL, 'width' => NULL, 'height' => NULL, 'alt' => '', 'title' => NULL, 'attributes' => [], 'sizes' => NULL, 'srcset' => [], 'style_name' => NULL],
+      'variables' => ['uri' => NULL, 'width' => NULL, 'height' => NULL, 'alt' => '', 'title' => NULL, 'attributes' => [], 'sizes' => NULL, 'srcset' => [], 'style_name' => NULL, 'timestamp' => NULL],
     ],
     'breadcrumb' => [
       'variables' => ['links' => []],
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index bf69b9044..27410ccf4 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -62,6 +62,10 @@ function template_preprocess_image_formatter(&$variables) {

   $item = $variables['item'];

+  if ($entity = $item->entity) {
+    $variables['image']['#timestamp'] = $item->entity->get('changed')->value;
+  }
+
   // Do not output an empty 'title' attribute.
   if (mb_strlen($item->title) != 0) {
     $variables['image']['#title'] = $item->title;
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 4c0e8cca9..c1402fa35 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -133,6 +133,7 @@ function image_theme() {
         'alt' => '',
         'title' => NULL,
         'attributes' => [],
+        'timestamp' => NULL,
       ],
     ],

@@ -308,6 +309,7 @@ function template_preprocess_image_style(&$variables) {
     '#height' => $dimensions['height'],
     '#attributes' => $variables['attributes'],
     '#style_name' => $variables['style_name'],
+    '#timestamp' => $variables['timestamp'],
   ];

   // If the current image toolkit supports this file type, prepare the URI for
diff --git a/core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php b/core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php
index b1355fe05..e2fb4bbb1 100644
--- a/core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php
+++ b/core/modules/image/tests/src/Functional/ImageFieldDisplayTest.php
@@ -102,12 +102,14 @@ public function _testImageFieldFormatters($scheme) {
     // Test that the default formatter is being used.
     $file = $node->{$field_name}->entity;
     $image_uri = $file->getFileUri();
+    $timestamp = $file->get('changed')->value;
     $image = [
       '#theme' => 'image',
       '#uri' => $image_uri,
       '#width' => 40,
       '#height' => 20,
       '#alt' => $alt,
+      '#timestamp' => $timestamp,
     ];
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
@@ -127,6 +129,7 @@ public function _testImageFieldFormatters($scheme) {
       '#width' => 40,
       '#height' => 20,
       '#alt' => $alt,
+      '#timestamp' => $timestamp,
     ];
     $default_output = '<a href="' . file_create_url($image_uri) . '">' . $renderer->renderRoot($image) . '</a>';
     $this->drupalGet('node/' . $nid);
@@ -162,6 +165,7 @@ public function _testImageFieldFormatters($scheme) {
       '#uri' => $image_uri,
       '#width' => 40,
       '#height' => 20,
+      '#timestamp' => $timestamp,
     ];
     $this->drupalGet('node/' . $nid);
     $this->assertCacheTag($file->getCacheTags()[0]);
@@ -171,7 +175,7 @@ public function _testImageFieldFormatters($scheme) {
       '//a[@href=:path]/img[@src=:url and @alt=:alt and @width=:width and @height=:height]',
       [
         ':path' => $node->toUrl()->toString(),
-        ':url' => file_url_transform_relative(file_create_url($image['#uri'])),
+        ':url' => file_url_transform_relative(file_create_url($image['#uri']) . '?timestamp=' . $timestamp),
         ':width' => $image['#width'],
         ':height' => $image['#height'],
         ':alt' => $alt,
@@ -195,6 +199,7 @@ public function _testImageFieldFormatters($scheme) {
       '#height' => 20,
       '#style_name' => 'thumbnail',
       '#alt' => $alt,
+      '#timestamp' => $timestamp,
     ];
     $default_output = $renderer->renderRoot($image_style);
     $this->drupalGet('node/' . $nid);
@@ -277,7 +282,7 @@ public function testImageFieldSettings() {
     $node_storage->resetCache([$nid]);
     $node = $node_storage->load($nid);
     $file = $node->{$field_name}->entity;
-
+    $timestamp = $file->get('changed')->value;
     $url = file_url_transform_relative(ImageStyle::load('medium')->buildUrl($file->getFileUri()));
     $this->assertTrue($this->cssSelect('img[width=40][height=20][class=image-style-medium][src="' . $url . '"]'));

@@ -289,6 +294,7 @@ public function testImageFieldSettings() {
       '#title' => $this->randomMachineName(),
       '#width' => 40,
       '#height' => 20,
+      '#timestamp' => $timestamp,
     ];
     $edit = [
       $field_name . '[0][alt]' => $image['#alt'],
@@ -379,6 +385,7 @@ public function testImageFieldDefaultImage() {
     $field_storage = FieldStorageConfig::loadByName('node', $field_name);
     $default_image = $field_storage->getSetting('default_image');
     $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $default_image['uuid']);
+    $timestamp = $file->get('changed')->value;
     $this->assertTrue($file->isPermanent(), 'The default image status is permanent.');
     $image = [
       '#theme' => 'image',
@@ -387,6 +394,8 @@ public function testImageFieldDefaultImage() {
       '#title' => $title,
       '#width' => 40,
       '#height' => 20,
+      '#timestamp' => $timestamp,
+
     ];
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->drupalGet('node/' . $node->id());
diff --git a/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php b/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
index 8a1c2c6e7..8eb52cb55 100644
--- a/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageThemeFunctionTest.php
@@ -105,10 +105,11 @@ public function testImageFormatterTheme() {
       '#url' => Url::fromUri('base:' . $path),
     ];

+    $timestamp = $entity->image_test->entity->get('changed')->value;
     // Test using theme_image_formatter() with a NULL value for the alt option.
     $element = $base_element;
     $this->setRawContent($renderer->renderRoot($element));
-    $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
+    $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height]', [':path' => base_path() . $path, ':url' => $url . '&timestamp=' . $timestamp, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
     $this->assertEqual(count($elements), 1, 'theme_image_formatter() correctly renders with a NULL value for the alt option.');

     // Test using theme_image_formatter() without an image title, alt text, or
@@ -116,7 +117,7 @@ public function testImageFormatterTheme() {
     $element = $base_element;
     $element['#item']->alt = '';
     $this->setRawContent($renderer->renderRoot($element));
-    $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height and @alt=""]', [':path' => base_path() . $path, ':url' => $url, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
+    $elements = $this->xpath('//a[@href=:path]/img[@src=:url and @width=:width and @height=:height and @alt=""]', [':path' => base_path() . $path, ':url' => $url . '&timestamp=' . $timestamp, ':width' => $image->getWidth(), ':height' => $image->getHeight()]);
     $this->assertEqual(count($elements), 1, 'theme_image_formatter() correctly renders without title, alt, or path options.');

     // Link the image to a fragment on the page, and not a full URL.
diff --git a/core/modules/rdf/tests/src/Functional/ImageFieldAttributesTest.php b/core/modules/rdf/tests/src/Functional/ImageFieldAttributesTest.php
index b8b471967..9990d5d4a 100644
--- a/core/modules/rdf/tests/src/Functional/ImageFieldAttributesTest.php
+++ b/core/modules/rdf/tests/src/Functional/ImageFieldAttributesTest.php
@@ -99,7 +99,7 @@ public function testNodeTeaser() {

     // Construct the node and image URIs for testing.
     $node_uri = $this->node->toUrl('canonical', ['absolute' => TRUE])->toString();
-    $image_uri = ImageStyle::load('medium')->buildUrl($this->file->getFileUri());
+    $image_uri = ImageStyle::load('medium')->buildUrl($this->file->getFileUri()) . '&timestamp=' . $this->file->get('changed')->value;;

     // Test relations from node to image.
     $expected_value = [
diff --git a/core/modules/rdf/tests/src/Functional/StandardProfileTest.php b/core/modules/rdf/tests/src/Functional/StandardProfileTest.php
index 8355c19c7..5646be0d2 100644
--- a/core/modules/rdf/tests/src/Functional/StandardProfileTest.php
+++ b/core/modules/rdf/tests/src/Functional/StandardProfileTest.php
@@ -227,7 +227,7 @@ protected function doFrontPageRdfaTests() {
     // @todo Once the image points to the original instead of the processed
     //   image, move this to testArticleProperties().
     $image_file = $this->article->get('field_image')->entity;
-    $image_uri = ImageStyle::load('medium')->buildUrl($image_file->getFileUri());
+    $image_uri = ImageStyle::load('medium')->buildUrl($image_file->getFileUri()) . '&timestamp=' . $this->file->get('changed')->value;;
     $expected_value = [
       'type' => 'uri',
       'value' => $image_uri,
@@ -256,11 +256,12 @@ protected function doArticleRdfaTests() {
     // Test the comment properties displayed on articles.
     $this->assertRdfaNodeCommentProperties($graph);

+    $timestamp = $this->article->get('field_image')->entity->get('changed')->value;
     // @todo Once the image points to the original instead of the processed
     //   image, move this to testArticleProperties().
     $expected_value = [
       'type' => 'uri',
-      'value' => $this->imageUri,
+      'value' => $this->imageUri . '&timestamp=' . $timestamp,
     ];
     $this->assertTrue($graph->hasProperty($this->articleUri, 'http://schema.org/image', $expected_value), "Article image was found (schema:image).");
   }
diff --git a/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
index ac3a0f007..eb54dbd1d 100644
--- a/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageFieldDisplayTest.php
@@ -186,13 +186,16 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles =
     $node = $node_storage->load($nid);

     // Test that the default formatter is being used.
-    $image_uri = File::load($node->{$field_name}->target_id)->getFileUri();
+    $file = File::load($node->{$field_name}->target_id);
+    $image_uri = $file->getFileUri();
+    $timestamp = $file->get('changed')->value;
     $image = [
       '#theme' => 'image',
       '#uri' => $image_uri,
       '#width' => 360,
       '#height' => 240,
       '#alt' => $alt,
+      '#timestamp' => $timestamp,
     ];
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
