diff --git a/reviewboard/datagrids/columns.py b/reviewboard/datagrids/columns.py
index a1eaeba051a8480761c34d5d1749d2a6d5d95fd0..956cbd419bf663b1528bd814407884a4b9ce0797 100644
--- a/reviewboard/datagrids/columns.py
+++ b/reviewboard/datagrids/columns.py
@@ -63,7 +63,7 @@ class BaseSubmitterColumn(Column):
             css_class='submitter-column',
             shrink=True,
             sortable=True,
-            link=True,
+            link=False,
             *args, **kwargs)
 
     def render_user(self, state, user):
@@ -620,7 +620,7 @@ class SummaryColumn(Column):
         super(SummaryColumn, self).__init__(
             label=_('Summary'),
             expand=True,
-            link=True,
+            link=False,
             css_class='summary',
             sortable=True,
             *args, **kwargs)
@@ -653,6 +653,7 @@ class SummaryColumn(Column):
     def render_data(self, state, review_request):
         """Return the rendered contents of the column."""
         summary = review_request.summary
+        url = review_request.get_absolute_url()
         labels = []
 
         if review_request.submitter_id == state.datagrid.request.user.id:
@@ -676,16 +677,20 @@ class SummaryColumn(Column):
         elif review_request.status == ReviewRequest.DISCARDED:
             labels.append(('label-discarded', _('Discarded')))
 
-        display_data = format_html_join(
-            '', '<label class="{0}">{1}</label>', labels)
+        result = [format_html('<a class="review-request-link" href="{0}">',
+                              url),
+                 format_html_join('', '<label class="{0}">{1}</label>', labels)
+                 ]
 
         if summary:
-            display_data += format_html('<span>{0}</span>', summary)
+            result.append(format_html('<span>{0}</span>', summary))
         else:
-            display_data += format_html('<span class="no-summary">{0}</span>',
-                                        _('No Summary'))
+            result.append(format_html('<span class="no-summary">{0}</span>',
+                                      _('No Summary')))
+
+        result.append('</a>')
 
-        return display_data
+        return ''.join(result)
 
 
 class ReviewSummaryColumn(SummaryColumn):
diff --git a/reviewboard/reviews/builtin_fields.py b/reviewboard/reviews/builtin_fields.py
index e99345828a63a318a6d2b56de00402bd861fb724..ae3f7d2e42619fb65905aa4c186b5355d2e8435b 100644
--- a/reviewboard/reviews/builtin_fields.py
+++ b/reviewboard/reviews/builtin_fields.py
@@ -381,7 +381,8 @@ class DependsOnField(BuiltinFieldMixin, BaseModelListEditableField):
 
     def render_item(self, item):
         rendered_item = format_html(
-            '<a href="{url}" title="{summary}">{id}</a>',
+            '<a href="{url}" title="{summary}"'
+            '   class="review-request-link">{id}</a>',
             url=item.get_absolute_url(),
             summary=item.summary,
             id=item.display_id)
@@ -408,7 +409,7 @@ class BlocksField(BuiltinFieldMixin, BaseReviewRequestField):
     def render_value(self, blocks):
         return format_html_join(
             ', ',
-            '<a href="{0}">{1}</a>',
+            '<a href="{0}" class="review-request-link">{1}</a>',
             [
                 (item.get_absolute_url(), item.display_id)
                 for item in blocks
diff --git a/reviewboard/reviews/urls.py b/reviewboard/reviews/urls.py
index 060acb630e1a88c0119b9aa7a3f69268f4714794..31ad30e479c799aaf98284115fde2738f9dbe251 100644
--- a/reviewboard/reviews/urls.py
+++ b/reviewboard/reviews/urls.py
@@ -127,5 +127,10 @@ urlpatterns = patterns(
     'reviewboard.reviews.views',
 
     url(r'^new/$', 'new_review_request', name="new-review-request"),
+
+    # Review Request info box
+    url(r'^(?P<review_request_id>[0-9]+)/infobox/$',
+        'review_request_infobox', name='review-request-infobox'),
+
     url(r'^(?P<review_request_id>[0-9]+)/', include(review_request_urls)),
 )
diff --git a/reviewboard/reviews/views.py b/reviewboard/reviews/views.py
index 4ab6fb18d40bb411ff3ff255d3c758abf51f1c77..811e57b0567417195ebc90e9c7d595b18374b2ad 100644
--- a/reviewboard/reviews/views.py
+++ b/reviewboard/reviews/views.py
@@ -20,7 +20,7 @@ from django.template.context import RequestContext
 from django.template.loader import render_to_string
 from django.utils import six, timezone
 from django.utils.decorators import method_decorator
-from django.utils.html import escape
+from django.utils.html import escape, format_html_join
 from django.utils.http import http_date
 from django.utils.safestring import mark_safe
 from django.utils.timezone import utc
@@ -1538,6 +1538,80 @@ def bug_infobox(request, review_request_id, bug_id,
     }))
 
 
+@check_login_required
+@check_local_site_access
+def review_request_infobox(request, review_request_id,
+                           template_name='reviews/review_request_infobox.html',
+                           local_site=None):
+    """Display a review request info popup.
+
+    This function produces the information needed to be displayed
+    in a summarized information box, upon hovering over a link to
+    a review request.
+
+    Args:
+        request (django.http.HttpRequest):
+            The request object.
+
+        review_request_id (int):
+            The ID number of the review request.
+
+        template_name (unicode):
+            The path at which the template for the review request infobox is.
+
+        local_site (reviewboard.site.models.LocalSite):
+            The review request's local site, if available.
+
+    Returns:
+        django.http.HttpResponse:
+        The rendered text from the template and dictionary
+        for review request infobox.
+    """
+    review_request, response = \
+        _find_review_request(request, review_request_id, local_site)
+
+    if not review_request:
+        return response
+
+    # Below code is heavily referenced from columns.py.
+    # It should be refactored.
+    labels = []
+
+    if (review_request.submitter_id == request.user.id and
+        not review_request.public and
+        review_request.status == ReviewRequest.PENDING_REVIEW):
+        labels.append(('label-draft', _('Draft')))
+
+    #if request.user.is_authenticated():
+    #    if review_request.visibility == ReviewRequestVisit.ARCHIVED:
+    #        labels.append(('label-archived', _('Archived')))
+    #    elif review_request.visibility == ReviewRequestVisit.MUTED:
+    #        labels.append(('label-muted', _('Muted')))
+
+    if review_request.status == ReviewRequest.SUBMITTED:
+        labels.append(('label-submitted', _('Submitted')))
+    elif review_request.status == ReviewRequest.DISCARDED:
+        labels.append(('label-discarded', _('Discarded')))
+
+    display_data = format_html_join('', '<label class="{0}">{1}</label>',
+                                    labels)
+
+    issue_total_count = (review_request.issue_open_count +
+                         review_request.issue_resolved_count +
+                         review_request.issue_dropped_count)
+
+    # Contains the three most recent reviews.
+    latest_reviews = list(review_request.reviews.order_by('-timestamp')[:3])
+
+    return render_to_response(template_name, RequestContext(request, {
+        'review_request': review_request,
+        'review_request_id': review_request_id,
+        'review_request_labels': display_data,
+        'review_request_issue_total_count': issue_total_count,
+        'review_request_latest_reviews': latest_reviews,
+    }))
+
+
 def _download_diff_file(modified, request, review_request_id, revision,
                         filediff_id, local_site=None):
     """Downloads an original or modified file from a diff.
diff --git a/reviewboard/static/rb/css/common.less b/reviewboard/static/rb/css/common.less
index fd46171fc3c12d367fc6d7f41fcc38949e1f2ac9..0e8da7913a95e219f6ab10721d595ffd50729a58 100644
--- a/reviewboard/static/rb/css/common.less
+++ b/reviewboard/static/rb/css/common.less
@@ -599,7 +599,130 @@
   }
 }
 
-.user_infobox, .bug_infobox {
+/****************************************************************************
+ * Review Request hover
+ ****************************************************************************/
+
+.review_request_infobox {
+  max-width: 50em;
+  padding: 0.5em;
+
+  .review-request-infobox-header {
+
+    .label-draft {
+      .review-request-label(@summary-label-draft-bg, @summary-label-draft-border-color, @summary-label-text-color)
+    }
+
+    .label-submitted {
+      .review-request-label(@summary-label-submitted-bg, @summary-label-submitted-border-color, @summary-label-submitted-text-color)
+    }
+
+    .label-discarded {
+      .review-request-label(@summary-label-discarded-bg, @summary-label-discarded-border-color, @summary-label-discarded-text-color)
+    }
+
+    .label-archived {
+      .review-request-label(@summary-label-archived-bg, @summary-label-archived-border-color, @summary-label-archived-text-color)
+    }
+
+    .label-muted {
+      .review-request-label(@summary-label-muted-bg, @summary-label-muted-border-color, @summary-label-muted-text-color)
+    }
+  }
+
+  .review-request-infobox-submitter {
+    margin-top: 1.2em;
+  }
+
+  .review-request-infobox-description {
+    line-height: 1.2em;
+    margin-right: -1em;
+    margin-top: 1.2em;
+    max-height: 3.6em;
+    max-width: 49em;
+    overflow: hidden;
+    padding-right: 1em;
+    position: relative;
+    text-align: justify;
+  }
+
+  /* For the ellipsis when cutting off the description at 3 lines. */
+  .review-request-infobox-description:before {
+    bottom: 0;
+    content: '...';
+    position: absolute;
+    right: 0;
+  }
+
+  .review-request-infobox-description:after {
+    background: #F9F9F9;
+    content: '';
+    height: 1em;
+    margin-top: 0.2em;
+    position: absolute;
+    right: 0;
+    width: 1em;
+  }
+
+  .review-request-infobox-issue-summary {
+    margin-top: 1.2em;
+
+    .issue-summary {
+      display: inline-block;
+      list-style: none;
+      margin: 0 2.5em 0 0;
+      padding-left: 3em;
+      vertical-align: bottom;
+    }
+
+    .issue-summary-all {
+      display: inline-block;
+      margin-left: 8em;
+    }
+  }
+
+  .review-request-latest-icon {
+    display: inline-block;
+
+    img {
+      border: 2px #F9F9F9 solid;
+      border-radius: 50%;
+      box-sizing: border-box;
+    }
+  }
+
+  .review-request-latest-summary {
+    .left-arrow-callout(#ECECEE);
+
+    background-color: #ECECEE;
+    border: 1px #888A85 solid;
+    border-radius: 6px;
+    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.15);
+    display: inline;
+    margin-bottom: 1.2em;
+    margin-left: 1.3em;
+    padding-bottom: 1.2em;
+    padding-top: 1.2em;
+    position: absolute;
+    width: 86%;
+
+    .review-request-latest-header {
+      color: black;
+      font-size: 110%;
+      margin-left: 0.8em;
+
+      .review-request-latest-time {
+        color: #555;
+        float: right;
+        font-size: 11px;
+        margin-right: 1.3em;
+      }
+    }
+  }
+}
+
+/* Styling rules that are being shared by every infobox. */
+.infobox {
   background: #F9F9F9;
   border: 1px #666666 solid;
   border-radius: 3px;
@@ -621,6 +744,7 @@
   }
 }
 
+
 /****************************************************************************
  * New Review Request
  ****************************************************************************/
diff --git a/reviewboard/static/rb/css/mixins/style.less b/reviewboard/static/rb/css/mixins/style.less
index a27a42718b58e80c1cbea938ed949424f6880053..2d37f6218d78d285735633076b53e739ab492e0f 100644
--- a/reviewboard/static/rb/css/mixins/style.less
+++ b/reviewboard/static/rb/css/mixins/style.less
@@ -123,3 +123,50 @@
   line-height: 16px;
   vertical-align: top;
 }
+
+/* Adds a left-facing arrow to the left-hand side of a box. */
+.left-arrow-callout(@color) {
+  position: relative;
+
+  &:before, &:after {
+    border: 1px transparent solid;
+    content: " ";
+    display: block;
+    height: 0;
+    left: -20px;
+    position: absolute;
+    right: 100%;
+    top: 12px;
+    width: 0;
+  }
+
+  &:before {
+    border-right-color: @box-border-color;
+    border-width: 10px;
+  }
+
+  &:after {
+    border-right-color: @color;
+    border-width: 9px;
+    margin-left: 2px;
+    margin-top: 1px;
+  }
+}
+
+/* Changes the color of an existing callout arrow. */
+.left-arrow-callout-color(@color) {
+  &:after {
+    border-right-color: @color;
+  }
+}
+
+/* Styles the status label of a review request. */
+.review-request-label(@color, @border-color, @text-color) {
+  background-color: @color;
+  border: 1px @border-color solid;
+  border-radius: 5px;
+  color: @text-color;
+  font-size: 75%;
+  font-weight: normal;
+  padding: 0.1em 0.35em 0.25em 0.35em;
+}
\ No newline at end of file
diff --git a/reviewboard/static/rb/css/pages/reviews.less b/reviewboard/static/rb/css/pages/reviews.less
index b72cad41741b6896f62c7c1e67a0a6d2ae03aa04..7f065e2706780858a75ccfababa16b75bc110546 100644
--- a/reviewboard/static/rb/css/pages/reviews.less
+++ b/reviewboard/static/rb/css/pages/reviews.less
@@ -16,42 +16,6 @@
  * Review-specific macros
  ****************************************************************************/
 
-/* Adds a left-facing arrow to the left-hand side of a box. */
-.left-arrow-callout(@color) {
-  position: relative;
-
-  &:before, &:after {
-    position: absolute;
-    left: -20px;
-    top: 12px;
-    right: 100%;
-    border: 1px transparent solid;
-    content: " ";
-    display: block;
-    width: 0;
-    height: 0;
-  }
-
-  &:before {
-    border-right-color: @box-border-color;
-    border-width: 10px;
-  }
-
-  &:after {
-    border-width: 9px;
-    border-right-color: @color;
-    margin-top: 1px;
-    margin-left: 2px;
-  }
-}
-
-/* Changes the color of an existing callout arrow. */
-.left-arrow-callout-color(@color) {
-  &:after {
-    border-right-color: @color;
-  }
-}
-
 .review-comments-inline() {
   .comment-author {
     margin-bottom: 1em;
diff --git a/reviewboard/static/rb/js/common.es6.js b/reviewboard/static/rb/js/common.es6.js
index 073a8c63c1b155f9400818c2cd1314be168569fe..9de931b71a573645e0ebbd2cac60c4df4c57f5d2 100644
--- a/reviewboard/static/rb/js/common.es6.js
+++ b/reviewboard/static/rb/js/common.es6.js
@@ -9,7 +9,7 @@ $.fn.infobox = function(id) {
     let $el = $(`.${id}`);
 
     if ($el.length === 0) {
-        $el = $('<div/>')
+        $el = $('<div class="infobox"/>')
             .addClass(id)
             .hide()
             .appendTo(document.body);
@@ -43,10 +43,16 @@ $.fn.bug_infobox = function() {
     return this;
 };
 
+$.fn.review_request_infobox = function() {
+    $(this).infobox('review_request_infobox');
+    return this;
+};
+
 
 $(document).ready(function() {
     $('.user').user_infobox();
     $('.bug').bug_infobox();
+    $('.review-request-link').review_request_infobox();
     $('time.timesince').timesince();
 
     $('.avatar').retinaAvatar();
diff --git a/reviewboard/static/rb/js/pages/views/datagridPageView.js b/reviewboard/static/rb/js/pages/views/datagridPageView.js
index 9ad2f657d879a7f555e4a7667da3dd9411a9cf8c..2b16a67639fc4cba28d1e118a7c900ce7c41241f 100644
--- a/reviewboard/static/rb/js/pages/views/datagridPageView.js
+++ b/reviewboard/static/rb/js/pages/views/datagridPageView.js
@@ -123,6 +123,7 @@ RB.DatagridPageView = Backbone.View.extend({
         this.$('time.timesince').timesince();
         this.$('.user').user_infobox();
         this.$('.bugs').find('a').bug_infobox();
+        this.$('.review-request-link').review_request_infobox();
 
         this.model.clearSelection();
 
diff --git a/reviewboard/static/rb/js/utils/linkifyUtils.es6.js b/reviewboard/static/rb/js/utils/linkifyUtils.es6.js
index a7ac9821d0a0479dc7a83e242719e42f44e22883..17179d70e18340eecf667de6c75373d20a7a17c3 100644
--- a/reviewboard/static/rb/js/utils/linkifyUtils.es6.js
+++ b/reviewboard/static/rb/js/utils/linkifyUtils.es6.js
@@ -72,7 +72,8 @@ RB.LinkifyUtils = {
 
                 const href = SITE_ROOT + url + (url.substr(-1) === '/' ? '' : '/');
 
-                return `${m1}<a target="_blank" href="${href}">/${url}</a>${extra}`;
+                return `${m1}<a target="_blank" href="${href}"
+                        class="review-request-link">/${url}</a>${extra}`;
             });
     },
 
diff --git a/reviewboard/static/rb/js/utils/tests/linkifyUtilsTests.js b/reviewboard/static/rb/js/utils/tests/linkifyUtilsTests.js
index 33c02c513dea8f008d95de2f5429d36ba47d2c9a..146725a655b242473e2a139d986dd269166f028c 100644
--- a/reviewboard/static/rb/js/utils/tests/linkifyUtilsTests.js
+++ b/reviewboard/static/rb/js/utils/tests/linkifyUtilsTests.js
@@ -28,8 +28,8 @@ suite('rb/utils/linkifyUtils', function() {
             RB.LinkifyUtils.linkifyChildren($el[0]);
 
             expect($el.html()).toBe(
-                '<span><a target="_blank" href="/r/123/">' +
-                '/r/123/</a></span>');
+                '<span><a target="_blank" href="/r/123/"' +
+                'class="review-request-link"> /r/123/</a></span>');
         });
 
         it('Skips <a> elements', function() {
@@ -116,12 +116,14 @@ suite('rb/utils/linkifyUtils', function() {
             describe('Review requests', function() {
                 it('/r/123', function() {
                     expect(RB.LinkifyUtils.linkifyText('/r/123')).toBe(
-                        '<a target="_blank" href="/r/123/">/r/123</a>');
+                        '<a target="_blank" href="/r/123/"' +
+                        'class="review-request-link">/r/123</a>');
                 });
 
                 it('/r/123/', function() {
                     expect(RB.LinkifyUtils.linkifyText('/r/123/')).toBe(
-                        '<a target="_blank" href="/r/123/">/r/123/</a>');
+                        '<a target="_blank" href="/r/123/"' +
+                        'class="review-request-link">/r/123/</a>');
                 });
             });
 
@@ -143,22 +145,26 @@ suite('rb/utils/linkifyUtils', function() {
         describe('Surrounded by', function() {
             it('(...)', function() {
                 expect(RB.LinkifyUtils.linkifyText('(/r/123/)')).toBe(
-                       '(<a target="_blank" href="/r/123/">/r/123/</a>)');
+                       '(<a target="_blank" href="/r/123/"' +
+                       'class="review-request-link">/r/123/</a>)');
             });
 
             it('[...]', function() {
                 expect(RB.LinkifyUtils.linkifyText('[/r/123/]')).toBe(
-                       '[<a target="_blank" href="/r/123/">/r/123/</a>]');
+                       '[<a target="_blank" href="/r/123/"' +
+                       'class="review-request-link">/r/123/</a>]');
             });
 
             it('{...}', function() {
                 expect(RB.LinkifyUtils.linkifyText('{/r/123/}')).toBe(
-                       '{<a target="_blank" href="/r/123/">/r/123/</a>}');
+                       '{<a target="_blank" href="/r/123/"' +
+                       'class="review-request-link">/r/123/</a>}');
             });
 
             it('<...>', function() {
                 expect(RB.LinkifyUtils.linkifyText('</r/123/>')).toBe(
-                       '&lt;<a target="_blank" href="/r/123/">/r/123/</a>&gt;');
+                       '&lt;<a target="_blank" href="/r/123/"' +
+                       'class="review-request-link">/r/123/</a>&gt;');
             });
 
             it('text', function() {
diff --git a/reviewboard/templates/reviews/review_request_infobox.html b/reviewboard/templates/reviews/review_request_infobox.html
new file mode 100644
index 0000000000000000000000000000000000000000..20b9bef76b95de5bd5240f5d6ab425a649f6e62b
--- /dev/null
+++ b/reviewboard/templates/reviews/review_request_infobox.html
@@ -0,0 +1,60 @@
+{% load avatars i18n %}
+
+<div class="review-request-infobox-content">
+ <div class="review-request-infobox-details">
+  <div class="review-request-infobox-header">
+   <h2><a href="{{review_request.get_absolute_url}}">#{{review_request_id}}</a>:
+    {{review_request_labels}} {{review_request.summary}}</h2>
+  </div>
+  <div class="review-request-infobox-submitter">
+   {% trans "Submitter:" %} {{review_request.submitter.full_name}}
+   <span class="username">({{review_request.submitter.username}})</span>
+  </div>
+  <div class="review-request-infobox-description">
+   {{review_request.description}}
+  </div>
+  <div class="review-request-infobox-issue-summary">
+   {# Almost identical code can be found in reviews/review_issue_summary_table.html #}
+   <ul class="issue-summary">
+    <li class="issue-summary" title="{% trans 'Open issues' %}">
+     <label><span class="rb-icon rb-icon-issue-open"></span></label>
+     <span id="open-counter" class="issue-counter-value">{{review_request.issue_open_count}}</span>
+    </li>
+    <li class="issue-summary" title="{% trans 'Resolved issues' %}">
+     <label><span class="rb-icon rb-icon-issue-resolved"></span></label>
+     <span id="resolved-counter" class="issue-counter-value">{{review_request.issue_resolved_count}}</span>
+    </li>
+    <li class="issue-summary" title="{% trans 'Dropped issues' %}">
+     <label><span class="rb-icon rb-icon-issue-dropped"></span></label>
+     <span id="dropped-counter" class="issue-counter-value">{{review_request.issue_dropped_count}}</span>
+    </li>
+    <li class="issue-summary-all" title="{% trans 'All issues' %}">
+     <label>{% trans "All Issues:" %}</label>
+     <span id="total-counter" class="issue-counter-value">{{review_request_issue_total_count}}</span>
+    </li>
+   </ul>
+  </div>
+  <div class="review-request-infobox-latest">
+   <h3>Latest Reviews</h3>
+{% for review in review_request_latest_reviews %}
+    <div class="review-request-latest-review">
+{%  if siteconfig_settings.avatars_enabled %}
+     <div class="review-request-latest-icon">
+      {% avatar review.user 48 %}
+     </div>
+{%  endif %}
+     <a href="{{review.get_absolute_url}}">
+      <div class="review-request-latest-summary">
+       <div class="review-request-latest-header">
+        <b>{{review.user.username}}</b>
+        <time class="review-request-latest-time" title="{{review.timestamp}}">
+         {{review.timestamp|timesince}}
+        </time>
+       </div>
+      </div>
+     </a>
+    </div>
+{% endfor %}
+  </div>
+ </div>
+</div>
\ No newline at end of file
