diff --git a/reviewboard/diffviewer/renderers.py b/reviewboard/diffviewer/renderers.py
index 09d84bbbbe36fdf2b07f83d73531b6069877b084..e96906020cb12791ceeccacc895bc1b015009e80 100644
--- a/reviewboard/diffviewer/renderers.py
+++ b/reviewboard/diffviewer/renderers.py
@@ -35,7 +35,8 @@ class DiffRenderer(object):
 
     def __init__(self, diff_file, chunk_index=None, highlighting=False,
                  collapse_all=True, lines_of_context=None, extra_context=None,
-                 allow_caching=True, template_name=default_template_name):
+                 allow_caching=True, template_name=default_template_name,
+                 show_deleted=False):
         self.diff_file = diff_file
         self.chunk_index = chunk_index
         self.highlighting = highlighting
@@ -45,6 +46,7 @@ class DiffRenderer(object):
         self.allow_caching = allow_caching
         self.template_name = template_name
         self.num_chunks = 0
+        self.show_deleted = show_deleted
 
         if self.lines_of_context and len(self.lines_of_context) == 1:
             # If we only have one value, then assume it represents before
@@ -127,6 +129,9 @@ class DiffRenderer(object):
         if self.highlighting:
             key += '-highlighting'
 
+        if self.show_deleted:
+            key += '-show_deleted'
+
         key += '-%s-%s' % (get_language(), settings.TEMPLATE_SERIAL)
 
         return key
@@ -237,6 +242,7 @@ class DiffRenderer(object):
             'lines_of_context': self.lines_of_context or (0, 0),
             'equal_lines': equal_lines,
             'standalone': self.chunk_index is not None,
+            'show_deleted': self.show_deleted,
         })
 
         return context
diff --git a/reviewboard/diffviewer/views.py b/reviewboard/diffviewer/views.py
index c23ade6070390616a52f15ed6e7d66627d08977e..28d83b9caac1bdcff3e190d93efdd012a02a563a 100644
--- a/reviewboard/diffviewer/views.py
+++ b/reviewboard/diffviewer/views.py
@@ -296,6 +296,8 @@ class DiffFragmentView(View):
                 The following keys are required: ``collapse_all`` and
                 ``highlighting``.
 
+                The following key is optional: ``show_deleted``.
+
             filediff_id (int):
                 The ID of the
                 :py:class:`~reviewboard.diffviewer.models.FileDiff` being
@@ -321,6 +323,11 @@ class DiffFragmentView(View):
             interfilediff_id,
             settings.TEMPLATE_SERIAL)
 
+        show_deleted = renderer_settings.get('show_deleted')
+
+        if show_deleted:
+            etag += ':%s' % show_deleted
+
         return encode_etag(etag)
 
     def process_diffset_info(self, diffset_or_id, filediff_id,
@@ -450,11 +457,14 @@ class DiffFragmentView(View):
         else:
             collapse_all = get_collapse_diff(self.request)
 
+        show_deleted = (self.request.GET.get('show-deleted') == '1')
+
         return {
             'chunk_index': chunk_index,
             'collapse_all': collapse_all,
             'highlighting': highlighting,
             'lines_of_context': lines_of_context,
+            'show_deleted': show_deleted,
         }
 
     def _get_requested_diff_file(self, diffset, filediff, interdiffset):
diff --git a/reviewboard/static/rb/css/pages/diffviewer.less b/reviewboard/static/rb/css/pages/diffviewer.less
index 2690d6a697a63d2ab3bc0f412572ea531ab99684..9fb6ab34e9c98ba5f0d330d6eb08cba4357a4c10 100644
--- a/reviewboard/static/rb/css/pages/diffviewer.less
+++ b/reviewboard/static/rb/css/pages/diffviewer.less
@@ -277,6 +277,11 @@
     &.deleted td {
       background: @diff-delete-color;
       padding: 1em;
+
+      a {
+        color: #0000FF;
+        text-decoration: underline;
+      }
     }
 
     &.new-empty-file td {
diff --git a/reviewboard/static/rb/js/diffviewer/models/diffReviewableModel.js b/reviewboard/static/rb/js/diffviewer/models/diffReviewableModel.js
index 5c405acaa86da962ee0c3910afc76fa5c987382e..70cbff8d88b530c27ff432b8d2e613027192c0c1 100644
--- a/reviewboard/static/rb/js/diffviewer/models/diffReviewableModel.js
+++ b/reviewboard/static/rb/js/diffviewer/models/diffReviewableModel.js
@@ -30,16 +30,41 @@ RB.DiffReviewable = RB.AbstractReviewable.extend({
         });
     },
 
-    /*
-     * Returns the rendered diff for a file.
+    /**
+     * Return the rendered diff for a file.
      *
      * The rendered file will be fetched from the server and eventually
      * returned as the argument to the success callback.
+     *
+     * Args:
+     *     callbacks (object):
+     *         The functions used to fetch the corresponding diff fragments.
+     *
+     *     context (object):
+     *         The context passed to each callback function.
+     *
+     *     options (object):
+     *         The option arguments that control the behavior of this function.
+     *
+     * Option Args:
+     *     showDeleted (boolean):
+     *         Determines whether or not we want to requeue the corresponding
+     *         diff in order to show its deleted content.
      */
-    getRenderedDiff: function(callbacks, context) {
+    getRenderedDiff: function(callbacks, context, options) {
+        var url = this._buildRenderedDiffURL() + '?index=' +
+                  this.get('fileIndex');
+
+        options = options || {};
+
+        if (options.showDeleted) {
+            url += '&show-deleted=1';
+        }
+
+        url += '&' + TEMPLATE_SERIAL;
+
         this._fetchFragment({
-            url: this._buildRenderedDiffURL() +
-                 '?index=' + this.get('fileIndex') + '&' + TEMPLATE_SERIAL,
+            url: url,
             noActivityIndicator: true
         }, callbacks, context);
     },
diff --git a/reviewboard/static/rb/js/diffviewer/views/diffReviewableView.js b/reviewboard/static/rb/js/diffviewer/views/diffReviewableView.js
index 3c603b68e4d6fee39cecb626aad806de030b0f54..e399ebb4b423b3a100810e15be210baf38b0d9ae 100644
--- a/reviewboard/static/rb/js/diffviewer/views/diffReviewableView.js
+++ b/reviewboard/static/rb/js/diffviewer/views/diffReviewableView.js
@@ -32,6 +32,7 @@ RB.DiffReviewableView = RB.AbstractReviewableView.extend({
         'click .moved-to, .moved-from': '_onMovedLineClicked',
         'click .diff-collapse-btn': '_onCollapseChunkClicked',
         'click .diff-expand-btn': '_onExpandChunkClicked',
+        'click .show-deleted-content-action': '_onShowDeletedClicked',
         'mouseup': '_onMouseUp'
     },
 
@@ -634,6 +635,22 @@ RB.DiffReviewableView = RB.AbstractReviewableView.extend({
 
         e.preventDefault();
         this._expandOrCollapse($target, false);
+    },
+
+    /**
+     * Handler for when show content is clicked.
+     *
+     * This requeues the corresponding diff to show its deleted content.
+     *
+     * Args:
+     *     e (Event):
+     *         The event that is triggered when show content is clicked.
+     */
+    _onShowDeletedClicked: function(e) {
+        e.preventDefault();
+        e.stopPropagation();
+
+        this.trigger('showDeletedClicked');
     }
 });
 
diff --git a/reviewboard/static/rb/js/pages/views/diffViewerPageView.js b/reviewboard/static/rb/js/pages/views/diffViewerPageView.js
index eb89ea4d8bbfc5de5ff98f8cb4ba844393681a25..d19424d419c46371784fbfd5ebe3113162322baf 100644
--- a/reviewboard/static/rb/js/pages/views/diffViewerPageView.js
+++ b/reviewboard/static/rb/js/pages/views/diffViewerPageView.js
@@ -82,7 +82,6 @@ RB.DiffViewerPageView = RB.ReviewablePageView.extend({
         });
 
         /*
-        /*
          * Begin managing the URL history for the page, so that we can
          * switch revisions and handle pagination while keeping the history
          * clean and the URLs representative of the current state.
@@ -268,51 +267,64 @@ RB.DiffViewerPageView = RB.ReviewablePageView.extend({
                 interdiffRevision = file.get('forceInterdiffRevision');
             }
 
-            this.queueLoadDiff(filediff.id,
-                               filediff.revision,
-                               interfilediff ? interfilediff.id : null,
-                               interdiffRevision,
-                               file.get('index'),
-                               file.get('commentCounts'));
+            this.queueLoadDiff(new RB.DiffReviewable({
+                reviewRequest: this.reviewRequest,
+                fileIndex: file.get('index'),
+                fileDiffID: filediff.id,
+                interFileDiffID: interfilediff ? interfilediff.id : null,
+                revision: filediff.revision,
+                interdiffRevision: interdiffRevision,
+                serializedCommentBlocks: file.get('commentCounts')
+            }));
         }, this);
 
         $.funcQueue('diff_files').start();
     },
 
-    /*
-     * Queues loading of a diff.
+    /**
+     * Queue the loading of the corresponding diff.
      *
      * When the diff is loaded, it will be placed into the appropriate location
      * in the diff viewer. The anchors on the page will be rebuilt. This will
      * then trigger the loading of the next file.
+     *
+     * Args:
+     *     diffReviewable (RB.DiffReviewable):
+     *         The diff reviewable for loading and reviewing the diff.
+     *
+     *     options (object):
+     *         The option arguments that control the behavior of this function.
+     *
+     * Option Args:
+     *     showDeleted (boolean):
+     *         Determines whether or not we want to requeue the corresponding
+     *         diff in order to show its deleted content.
      */
-    queueLoadDiff: function(fileDiffID, fileDiffRevision,
-                            interFileDiffID, interdiffRevision,
-                            fileIndex, serializedCommentBlocks) {
-        var diffReviewable = new RB.DiffReviewable({
-            reviewRequest: this.reviewRequest,
-            fileIndex: fileIndex,
-            fileDiffID: fileDiffID,
-            interFileDiffID: interFileDiffID,
-            revision: fileDiffRevision,
-            interdiffRevision: interdiffRevision,
-            serializedCommentBlocks: serializedCommentBlocks
-        });
+    queueLoadDiff: function(diffReviewable, options) {
+        var fileDiffID = diffReviewable.get('fileDiffID'),
+            prefix;
+
+        options = options || {};
 
         $.funcQueue('diff_files').add(function() {
-            if ($('#file' + fileDiffID).length === 1) {
+            if (!options.showDeleted && $('#file' + fileDiffID).length === 1) {
                 /*
-                 * We already have this one. This is probably a pre-loaded file.
+                 * We already have this diff (probably pre-loaded), and we
+                 * don't want to requeue it to show its deleted content.
                  */
                 this._renderFileDiff(diffReviewable);
             } else {
+                /*
+                 * We either want to queue this diff for the first time, or we
+                 * want to requeue it to show its deleted content.
+                 */
+                prefix = (options.showDeleted ? '#file' : '#file_container_');
                 diffReviewable.getRenderedDiff({
                     complete: function(xhr) {
-                        $('#file_container_' + fileDiffID)
-                            .replaceWith(xhr.responseText);
+                        $(prefix + fileDiffID).replaceWith(xhr.responseText);
                         this._renderFileDiff(diffReviewable);
                     }
-                }, this);
+                }, this, options);
             }
         }, this);
     },
@@ -335,7 +347,7 @@ RB.DiffViewerPageView = RB.ReviewablePageView.extend({
 
         if ($el.length === 0) {
             /*
-             * The user changed revsions before the file finished loading, and
+             * The user changed revisions before the file finished loading, and
              * the target element no longer exists. Just return.
              */
             $.funcQueue('diff_files').next();
@@ -403,6 +415,11 @@ RB.DiffViewerPageView = RB.ReviewablePageView.extend({
             }
         }
 
+        this.listenTo(diffReviewableView, 'showDeletedClicked', function() {
+            this.queueLoadDiff(diffReviewable, {showDeleted: true});
+            $.funcQueue('diff_files').start();
+        });
+
         $.funcQueue('diff_files').next();
     },
 
diff --git a/reviewboard/templates/diffviewer/diff_file_fragment.html b/reviewboard/templates/diffviewer/diff_file_fragment.html
index 515e3c78786b2af2d1fb1fd1f7fff3dee3dce0d9..85e8562c81dda3f1f844042c54621abe51189800 100644
--- a/reviewboard/templates/diffviewer/diff_file_fragment.html
+++ b/reviewboard/templates/diffviewer/diff_file_fragment.html
@@ -188,14 +188,15 @@
    <td colspan="4">{% trans "This is an empty file." %}</td>
   </tr>
  </tbody>
-{% elif file.deleted %}
+{% elif file.deleted and not show_deleted %}
  <tbody class="deleted">
   <tr>
    <td colspan="4">
 {%  if file.num_changes == 0 %}
 {%   trans "This empty file was deleted. The content cannot be displayed." %}
 {%  else %}
-{%   trans "This file was deleted. The content cannot be displayed." %}
+{%   trans "This file was deleted." %}
+    <a class="show-deleted-content-action" href="#">{% trans "Show content." %}</a>
 {%  endif %}
    </td>
   </tr>
