diff --git a/css/tmgmt.admin.css b/css/tmgmt.admin.css
index 632956d..a0468d8 100644
--- a/css/tmgmt.admin.css
+++ b/css/tmgmt.admin.css
@@ -55,6 +55,10 @@ table.tmgmt-ui-review tbody th {
   font-weight: bold;
 }
 
+.tmgmt-review-message-inline {
+  display: inline;
+}
+
 .tmgmt-ui-data-item-label .form-item {
   /* Get the label out of way, so the status icon can be placed at the same
   relative position */
@@ -230,3 +234,7 @@ td.views-field-tjid a {
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
+table.diff {
+  table-layout: auto;
+}
diff --git a/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php b/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
index 61fd04d..a24d367 100644
--- a/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
+++ b/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
@@ -77,7 +77,7 @@ class ContentEntitySource extends SourcePluginBase implements SourcePreviewInter
   public function getData(JobItemInterface $job_item) {
     $entity = entity_load($job_item->getItemType(), $job_item->getItemId());
     if (!$entity) {
-      throw new TMGMTException(t('Unable to load entity %type with id %id', array('%type' => $job_item->getItemType(), $job_item->getItemId())));
+      throw new TMGMTException(t('Unable to load entity %type with id %id', array('%type' => $job_item->getItemType(), '%id' => $job_item->getItemId())));
     }
     $languages = \Drupal::languageManager()->getLanguages();
     $id = $entity->language()->getId();
diff --git a/src/Form/JobItemForm.php b/src/Form/JobItemForm.php
index 72e7540..2116539 100644
--- a/src/Form/JobItemForm.php
+++ b/src/Form/JobItemForm.php
@@ -7,12 +7,15 @@
 
 namespace Drupal\tmgmt\Form;
 
+use Drupal\Component\Diff\Diff;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Xss;
+use \Drupal\Core\Diff\DiffFormatter;
 use Drupal\tmgmt\Entity\JobItem;
 use Drupal\tmgmt\JobItemInterface;
 use Drupal\tmgmt\SourcePreviewInterface;
+use Drupal\tmgmt\TMGMTException;
 use Drupal\tmgmt\TranslatorRejectDataInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
@@ -121,6 +124,7 @@ class JobItemForm extends TmgmtFormBase {
     );
     // Build the review form.
     $data = $item->getData();
+    $this->hasChangedSource(\Drupal::service('tmgmt.data')->flatten($data), $form_state);
     // Need to keep the first hierarchy. So flatten must take place inside
     // of the foreach loop.
     $zebra = 'even';
@@ -552,11 +556,89 @@ class JobItemForm extends TmgmtFormBase {
           );
         }
 
-        if(isset($form_state->get('validation_messages')[$target_key])) {
+        if (isset($form_state->get('source_changed')[$target_key])) {
+          if ($form_state->hasValue('show_diff' . $key) && $form_state->getValue('show_diff' . $key, FALSE)) {
+            $keys = \Drupal::service('tmgmt.data')->ensureArrayKey($target_key);
+
+            try {
+              $new_data = \Drupal::service('tmgmt.data')->flatten($job_item->getSourceData());
+            }
+            catch (TMGMTException $e) {
+              $new_data = [];
+            }
+
+            $current_data = $job_item->getData($keys);
+
+            $diff_header = ['', t('Current text'), '', t('New text')];
+
+            $current_lines = explode("\n", $current_data['#text']);
+            $new_lines = explode("\n", isset($new_data[$key]) ? $new_data[$key]['#text'] : '');
+
+            $diff_formatter = new DiffFormatter($this->configFactory());
+            $diff = new Diff($current_lines, $new_lines);
+
+            $diff_rows = $diff_formatter->format($diff);
+            // Unset start block.
+            unset($diff_rows[0]);
+
+            $form[$target_key]['source_changed']['diff'] = [
+              '#type' => 'table',
+              '#header' => $diff_header,
+              '#rows' => $diff_rows,
+              '#empty' => $this->t('No visible changes'),
+              '#attributes' => [
+                'class' => ['diff'],
+              ],
+            ];
+            $form[$target_key]['source_changed']['#attached']['library'][] = 'system/diff';
+            $form[$target_key]['diff_actions'] = [
+              '#type' => 'container',
+            ];
+            $form[$target_key]['diff_actions']['resolve-diff'] = [
+              '#type' => 'submit',
+              '#value' => 'Resolve',
+              '#attributes' => ['title' => t('Apply the changes of the source.')],
+              '#name' => 'resolve-diff-' . $target_key,
+              '#data_item_key' => $key,
+              '#submit' => ['::resolveDiff'],
+              '#ajax' => [
+                'callback' => '::ajaxReviewForm',
+                'wrapper' => $form['#ajaxid'],
+              ],
+            ];
+          }
+          else {
+            $form[$target_key]['source_changed'] = [
+              '#title' => t('Source changed'),
+              '#type' => 'item',
+              '#value' => $form_state->get('source_changed')[$target_key],
+            ];
+            $form[$target_key]['source_changed']['message'] = [
+              '#title' => t('Source changed'),
+              '#type' => 'item',
+              '#value' => $form_state->get('source_changed')[$target_key],
+            ];
+            if (!$form_state->hasValue('removed' . $target_key)) {
+              $form[$target_key]['source_changed']['diff_button'] = [
+                '#type' => 'submit',
+                '#value' => 'Show diff',
+                '#name' => 'diff-button-' . $target_key,
+                '#data_item_key' => $key,
+                '#submit' => ['::showDiff'],
+                '#ajax' => [
+                  'callback' => '::ajaxReviewForm',
+                  'wrapper' => $form['#ajaxid'],
+                ],
+              ];
+            }
+          }
+        }
+
+        if (isset($form_state->get('validation_messages')[$target_key])) {
           $form[$target_key]['validation_message'] = array(
             '#title' => t('Validation message'),
             '#type' => 'item',
-            '#value' =>  htmlspecialchars($form_state->get('validation_messages')[$target_key]),
+            '#value' => htmlspecialchars($form_state->get('validation_messages')[$target_key]),
           );
         }
 
@@ -694,4 +776,71 @@ class JobItemForm extends TmgmtFormBase {
     return $counted_tags;
   }
 
+  /**
+   * Check if the source has changed.
+   *
+   * @param array $data
+   *   The data items.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
+   */
+  public function hasChangedSource(array $data, FormStateInterface $form_state) {
+    $item = $this->entity;
+    $source_changed = [];
+    foreach ($data as $target_key => $value) {
+      if (is_array($value) && isset($value['#translate']) && $value['#translate']) {
+        $field = str_replace('][', '|', $target_key);
+        $keys = \Drupal::service('tmgmt.data')->ensureArrayKey($field);
+        try {
+          $new_data = \Drupal::service('tmgmt.data')->flatten($item->getSourceData());
+        }
+        catch (TMGMTException $e) {
+          drupal_set_message(t('The source does not exist any more.'), 'error');
+          return;
+        }
+        $current_data = $item->getData($keys);
+        if (!isset($new_data[$target_key])) {
+          $source_changed[$field] = 'This data item has been removed from the source.';
+          $form_state->setValue('removed' . $field, TRUE);
+        }
+        elseif ($current_data['#text'] != $new_data[$target_key]['#text']) {
+          $source_changed[$field] = 'The source has changed.';
+        }
+      }
+    }
+    $form_state->set('source_changed', $source_changed);
+  }
+
+  /**
+   * Submit handler to show the diff table of the source.
+   */
+  public function showDiff(array $form, FormStateInterface $form_state) {
+    $target_key = $form_state->getTriggeringElement()['#data_item_key'];
+    $form_state->setValue('show_diff' . $target_key, TRUE);
+    $form_state->setRebuild();
+  }
+
+  /**
+   * Submit handler to resolve the diff updating the Job Item source.
+   */
+  public function resolveDiff(array $form, FormStateInterface $form_state) {
+    $item = $this->entity;
+    $target_key = $form_state->getTriggeringElement()['#data_item_key'];
+    $tmgmt_data_item = str_replace('][', '|', $target_key);
+    $keys = \Drupal::service('tmgmt.data')->ensureArrayKey($tmgmt_data_item);
+    $first_key = reset($keys);
+    $source_data = $item->getSourceData();
+    $new_data = \Drupal::service('tmgmt.data')->flatten($source_data)[$target_key];
+    $item->updateData($keys, $new_data, TRUE);
+    if (isset($source_data[$first_key]['#label'])) {
+      $item->addMessage('The conflict in the data item source "@data_item" has been resolved.', ['@data_item' => $source_data[$first_key]['#label']]);
+    }
+    else {
+      $item->addMessage('The conflict in the data item source has been resolved.');
+    }
+    $item->save();
+    $form_state->setValue('show_diff' . $target_key, FALSE);
+    $form_state->setRebuild();
+  }
+
 }
diff --git a/src/Tests/TMGMTUiReviewTest.php b/src/Tests/TMGMTUiReviewTest.php
index d92c360..bc509e2 100644
--- a/src/Tests/TMGMTUiReviewTest.php
+++ b/src/Tests/TMGMTUiReviewTest.php
@@ -533,4 +533,78 @@ class TMGMTUiReviewTest extends EntityTestBase {
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-single-wrapper"]/table/tbody/tr[3]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Title');
   }
+
+  /**
+   * Tests update the source and show the diff of the source.
+   */
+  public function testSourceUpdate() {
+    // Create the original data items.
+    $job = $this->createJob('en', 'de');
+    $job->translator = $this->default_translator;
+    $job->save();
+    \Drupal::state()->set('tmgmt.test_source_data', [
+      'title' => [
+        '#label' => 'Example text 1',
+        'deep_nesting' => [
+          '#text' => 'Text for job item with type test and id 1.',
+          '#label' => 'Example text 1',
+          '#translate' => TRUE,
+        ],
+      ],
+      'sayonara_text' => [
+        '#label' => 'Example text 2',
+        'deep_nesting' => [
+          '#text' => 'This text will end badly.',
+          '#label' => 'Example text 2',
+          '#translate' => TRUE,
+        ],
+      ],
+    ]);
+    $job->addItem('test_source', 'test', '1');
+    $job->save();
+
+    $edit = array(
+      'target_language' => 'de',
+      'settings[action]' => 'submit',
+    );
+    $this->drupalPostForm('admin/tmgmt/jobs/' . $job->id(), $edit, t('Submit to provider'));
+
+    $job->requestTranslation();
+
+    // Modify the source.
+    \Drupal::state()->set('tmgmt.test_source_data', array(
+      'title' => array(
+        '#label' => 'Example text modified',
+        'deep_nesting' => array(
+          '#text' => 'This source has been changed.',
+          '#label' => 'Example text modified',
+          '#translate' => TRUE,
+        ),
+      ),
+    ));
+
+    // Show a message informing of the conflicts in the sources.
+    $this->drupalGet('admin/tmgmt/items/1');
+    $this->assertText('The source has changed.');
+    $this->assertText('This data item has been removed from the source.');
+
+    // Show diff.
+    $this->drupalPostAjaxForm(NULL, [], 'diff-button-title|deep_nesting');
+    $this->assertNoText('The source has changed.');
+    $this->assertText('Text for job item with type test and id 1.');
+    $this->assertText('This source has been changed.');
+    $this->assertText('This data item has been removed from the source.');
+
+    // Resolve the first data item.
+    $this->drupalPostAjaxForm(NULL, [], 'resolve-diff-title|deep_nesting');
+    $this->assertText('The conflict in the data item source "Example text modified" has been resolved.');
+    $this->assertNoText('The source has changed.');
+    $xpath = $this->xpath('//*[@name="title|deep_nesting[source]"]')[0];
+    $this->assertEqual($xpath, 'This source has been changed.');
+
+    // Check the other data item was not modified.
+    $this->assertText('This data item has been removed from the source.');
+    $this->assertText('This text will end badly.');
+  }
+
 }
diff --git a/tmgmt.theme.inc b/tmgmt.theme.inc
index db3e051..e27e610 100644
--- a/tmgmt.theme.inc
+++ b/tmgmt.theme.inc
@@ -239,6 +239,7 @@ function theme_tmgmt_translator_review_form($variables) {
   $result = '';
   $labels = '';
   $parent_label = '';
+  $source_changed = '';
   $validation_message = '';
   $element_groups = array();
   $element_group = '';
@@ -265,6 +266,18 @@ function theme_tmgmt_translator_review_form($variables) {
         $element_group = '<tr>' . tmgmt_build_table_cell($cell, TRUE) . '</tr>';
       }
     }
+    if (isset($element[$key]['source_changed'])) {
+      if (isset($element[$key]['source_changed']['message'])) {
+        $source_changed = '<div class="tmgmt_source_changed"><div class="messages messages--warning"><span class="tmgmt-review-message-inline"><span>' . $element[$key]['source_changed']['message']['#value'] . '</span>' . \Drupal::service('renderer')
+            ->render($element[$key]['source_changed']['diff_button']) . '</span></div></div>';
+        $diff_actions = '';
+      }
+      else {
+        $source_changed = \Drupal::service('renderer')->render($element[$key]['source_changed']);
+        $diff_actions = \Drupal::service('renderer')->render($element[$key]['diff_actions']);
+      }
+      $source_changed = '<tr><td></td><td colspan="2">' . $source_changed . '</td><td class="tmgmt-ui-data-item-actions">' . $diff_actions . '</td></tr>';
+    }
     if (isset($element[$key]['validation_message'])) {
       $validation_message = '<div class="tmgmt_validation_message"> <p class="messages messages--warning">' . $element[$key]['validation_message']['#value'] . '</p> </div>';
     }
@@ -272,7 +285,7 @@ function theme_tmgmt_translator_review_form($variables) {
   }
 
   // Append the last group to the group collection.
-  $element_groups[] = '<tbody>' . $element_group . '</tbody>';
+  $element_groups[] = '<tbody>' . $element_group . $source_changed . '</tbody>';
 
   // Display the label of all element groups inside a table header.
   if (!empty($parent_label)) {
