diff --git a/src/Tests/TokenFieldUiTest.php b/src/Tests/TokenFieldUiTest.php
index 37c80f4..d2273bc 100644
--- a/src/Tests/TokenFieldUiTest.php
+++ b/src/Tests/TokenFieldUiTest.php
@@ -3,6 +3,9 @@
 namespace Drupal\token\Tests;
 
 use Drupal\node\Entity\NodeType;
+use Drupal\node\Entity\Node;
+use Drupal\file\Entity\File;
+use Drupal\image\Entity\ImageStyle;
 
 /**
  * Tests field ui.
@@ -60,6 +63,17 @@ class TokenFieldUiTest extends TokenTestBase {
       'entity_type' => 'node',
       'bundle' => 'article',
     ))->save();
+    entity_create('field_storage_config', array(
+      'field_name' => 'field_image_2',
+      'entity_type' => 'node',
+      'type' => 'image',
+    ))->save();
+    entity_create('field_config', array(
+      'field_name' => 'field_image_2',
+      'label' => 'Image 2',
+      'entity_type' => 'node',
+      'bundle' => 'article',
+    ))->save();
 
     entity_get_form_display('node', 'article', 'default')
       ->setComponent('field_body', [
@@ -94,4 +108,99 @@ class TokenFieldUiTest extends TokenTestBase {
     $this->drupalGet('node/add/article');
     $this->assertText('The site is called Drupal.');
   }
+
+  /**
+   * Test that tokens are correctly provided and replaced for the image fields.
+   */
+  public function testImageFieldTokens() {
+    // Generate 2 different test images.
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example1.png');
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/loading.gif', 'public://example2.gif');
+
+    // Resize the test images so that they will be scaled down during token
+    // replacement.
+    $image1 = \Drupal::service('image.factory')->get('public://example1.png');
+    $image1->resize(500, 500);
+    $image1->save();
+    $image2 = \Drupal::service('image.factory')->get('public://example2.gif');
+    $image2->resize(500, 500);
+    $image2->save();
+
+    /** @var \Drupal\file\Entity\File $image1 */
+    $image1 = File::create(['uri' => 'public://example1.png']);
+    $image1->save();
+    /** @var \Drupal\file\Entity\File $image2 */
+    $image2 = File::create(['uri' => 'public://example2.gif']);
+    $image2->save();
+
+    $node = Node::create([
+      'title' => 'Test node title',
+      'type' => 'article',
+      'field_image' => [
+        [
+          'target_id' => $image1->id(),
+        ],
+      ],
+      'field_image_2' => [
+        [
+          'target_id' => $image2->id(),
+        ],
+      ],
+    ]);
+    $node->save();
+
+    // Obtain the file size and dimension of the images that will be scaled
+    // down during token replacement by applying the styles here.
+    $style = ImageStyle::load('thumbnail');
+    $style->createDerivative('public://example1.png', 'public://styles/thumbnail/public/example1-test.png');
+    $style->createDerivative('public://example2.gif', 'public://styles/thumbnail/public/example2-test.gif');
+    $image_1_thumbnail = \Drupal::service('image.factory')->get('public://styles/thumbnail/public/example1-test.png');
+    $image_2_thumbnail = \Drupal::service('image.factory')->get('public://styles/thumbnail/public/example2-test.gif');
+    $style = ImageStyle::load('medium');
+    $style->createDerivative('public://example1.png', 'public://styles/medium/public/example1-test.png');
+    $style->createDerivative('public://example2.gif', 'public://styles/medium/public/example2-test.gif');
+    $image_1_medium = \Drupal::service('image.factory')->get('public://styles/medium/public/example1-test.png');
+    $image_2_medium = \Drupal::service('image.factory')->get('public://styles/medium/public/example2-test.gif');
+    $style = ImageStyle::load('large');
+    $style->createDerivative('public://example1.png', 'public://styles/large/public/example1-test.png');
+    $style->createDerivative('public://example2.gif', 'public://styles/large/public/example2-test.gif');
+    $image_1_large = \Drupal::service('image.factory')->get('public://styles/large/public/example1-test.png');
+    $image_2_large = \Drupal::service('image.factory')->get('public://styles/large/public/example2-test.gif');
+
+    $tokens = [
+      // field_image
+      'field_image:image_styles:thumbnail:mimetype' => 'image/png',
+      'field_image:image_styles:medium:mimetype' => 'image/png',
+      'field_image:image_styles:large:mimetype' => 'image/png',
+      'field_image:image_styles:thumbnail:filesize' => $image_1_thumbnail->getFileSize(),
+      'field_image:image_styles:medium:filesize' => $image_1_medium->getFileSize(),
+      'field_image:image_styles:large:filesize' => $image_1_large->getFileSize(),
+      'field_image:image_styles:thumbnail:height' => $image_1_thumbnail->getHeight(),
+      'field_image:image_styles:medium:height' => $image_1_medium->getHeight(),
+      'field_image:image_styles:large:height' => $image_1_large->getHeight(),
+      'field_image:image_styles:thumbnail:width' => $image_1_thumbnail->getWidth(),
+      'field_image:image_styles:medium:width' => $image_1_medium->getWidth(),
+      'field_image:image_styles:large:width' => $image_1_large->getWidth(),
+      'field_image:image_styles:thumbnail:uri' => 'public://styles/thumbnail/public/example1.png',
+      'field_image:image_styles:medium:uri' => 'public://styles/medium/public/example1.png',
+      'field_image:image_styles:large:uri' => 'public://styles/large/public/example1.png',
+      // field_image_2
+      'field_image_2:image_styles:thumbnail:mimetype' => 'image/gif',
+      'field_image_2:image_styles:medium:mimetype' => 'image/gif',
+      'field_image_2:image_styles:large:mimetype' => 'image/gif',
+      'field_image_2:image_styles:thumbnail:filesize' => $image_2_thumbnail->getFileSize(),
+      'field_image_2:image_styles:medium:filesize' => $image_2_medium->getFileSize(),
+      'field_image_2:image_styles:large:filesize' => $image_2_large->getFileSize(),
+      'field_image_2:image_styles:thumbnail:height' => $image_2_thumbnail->getHeight(),
+      'field_image_2:image_styles:medium:height' => $image_2_medium->getHeight(),
+      'field_image_2:image_styles:large:height' => $image_2_large->getHeight(),
+      'field_image_2:image_styles:thumbnail:width' => $image_2_thumbnail->getWidth(),
+      'field_image_2:image_styles:medium:width' => $image_2_medium->getWidth(),
+      'field_image_2:image_styles:large:width' => $image_2_large->getWidth(),
+      'field_image_2:image_styles:thumbnail:uri' => 'public://styles/thumbnail/public/example2.gif',
+      'field_image_2:image_styles:medium:uri' => 'public://styles/medium/public/example2.gif',
+      'field_image_2:image_styles:large:uri' => 'public://styles/large/public/example2.gif',
+    ];
+    $this->assertTokens('node', ['node' => $node], $tokens);
+  }
 }
diff --git a/token.tokens.inc b/token.tokens.inc
index 7c30ead..1b200eb 100644
--- a/token.tokens.inc
+++ b/token.tokens.inc
@@ -22,6 +22,7 @@ use Drupal\user\UserInterface;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\image\Entity\ImageStyle;
 
 /**
  * Implements hook_token_info_alter().
@@ -381,6 +382,60 @@ function token_token_info() {
     'dynamic' => TRUE,
   );
 
+  // Provide image_field tokens for the different image styles.
+  if (\Drupal::moduleHandler()->moduleExists('image')) {
+    $info['types']['image_field'] = [
+      'name' => t('Image field'),
+      'needs-data' => 'image_field',
+      'module' => 'token',
+      'nested' => TRUE,
+    ];
+
+    $info['tokens']['image_field']['image_styles'] = [
+      'name' => t('Image styles'),
+      'description' => t('The image styles.'),
+      'type' => 'image_styles',
+    ];
+
+    $info['types']['image_styles'] = [
+      'name' => t('Image styles'),
+      'needs-data' => 'image_styles',
+      'module' => 'token',
+      'nested' => TRUE,
+    ];
+
+    $image_styles = image_style_options(FALSE);
+    foreach ($image_styles as $style => $description) {
+      $info['tokens']['image_styles'][$style] = [
+        'name' => $style,
+        'description' => t('@description image.', ['@description' => $description]),
+        'type' => 'image_style',
+      ];
+    }
+
+    // Provide additional image_style tokens.
+    $info['tokens']['image_style']['mimetype'] = [
+      'name' => t('MIME type'),
+      'description' => t('The MIME type (image/png, image/bmp, etc.) of the image.'),
+    ];
+    $info['tokens']['image_style']['filesize'] = [
+      'name' => t('File size'),
+      'description' => t('The file size of the image.'),
+    ];
+    $info['tokens']['image_style']['height'] = [
+      'name' => t('Height'),
+      'description' => t('The height the image, in pixels.'),
+    ];
+    $info['tokens']['image_style']['width'] = [
+      'name' => t('Width'),
+      'description' => t('The width of the image, in pixels.'),
+    ];
+    $info['tokens']['image_style']['uri'] = [
+      'name' => t('URI'),
+      'description' => t('The URI to the image.'),
+    ];
+  }
+
   return $info;
 }
 
@@ -436,6 +491,55 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
     $node = $data['node'];
 
     foreach ($tokens as $name => $original) {
+      $parts = explode(':', $name);
+      if ($node->hasField($parts[0]) && \Drupal::moduleHandler()->moduleExists('image')) {
+        $field = $node->get($parts[0]);
+        $image_styles = image_style_options(FALSE);
+        if ((count($parts) == 4) && array_key_exists($parts[2], $image_styles) && ($field->getFieldDefinition()->getType() == 'image')) {
+          // Token is of the form {field_name}:{image_style}:{token}. An image
+          // derivative of the original has to be created first. Integration of
+          // Drupal 7's Imagecache Token module.
+          /** @var \Drupal\file\Entity\File $field_image */
+          $field_image = $field->entity;
+          $original_uri = $field_image->getFileUri();
+          $style = ImageStyle::load($parts[2]);
+          $derivative_uri = $style->buildUri($original_uri);
+
+          if (!file_exists($derivative_uri)) {
+            // If the image derivative already exists, no need to re-generate it.
+            $derivative_exists = $style->createDerivative($original_uri, $derivative_uri);
+          }
+          else {
+            $derivative_exists = TRUE;
+          }
+
+          if ($derivative_exists) {
+            /** @var \Drupal\Core\Image\Image $image */
+            $image = \Drupal::service('image.factory')->get($derivative_uri);
+            // Generate the replacement token.
+            switch ($parts[3]) {
+              case 'mimetype':
+                $replacements[$original] = $image->getMimeType();
+                break;
+              case 'filesize' :
+                $replacements[$original] = $image->getFileSize();
+                break;
+              case 'height' :
+                $replacements[$original] = $image->getHeight();
+                break;
+              case 'width' :
+                $replacements[$original] = $image->getWidth();
+                break;
+              case 'uri' :
+                $replacements[$original] = $derivative_uri;
+                break;
+            }
+          }
+          continue;
+        }
+      }
+
+      // Other tokens.
       switch ($name) {
         case 'log':
           $replacements[$original] = (string) $node->revision_log->value;
@@ -1244,6 +1348,14 @@ function field_token_info_alter(&$info) {
         'needs-data' => $field_token_name,
         'nested' => TRUE,
       ];
+
+      // For fields of type image, the field's type is changed and field
+      // properties are not added.
+      if (($field->getType() == 'image') && \Drupal::moduleHandler()->moduleExists('image')) {
+        $info['tokens'][$token_type][$field_name]['type'] = 'image_field';
+        continue;
+      }
+
       // Field list token type.
       if ($cardinality > 1) {
         $info['types']["list<$field_token_name>"] = array(
