diff --git a/tracker/issueimport.py b/tracker/issueimport.py
new file mode 100644
index 0000000..1e0289b
--- /dev/null
+++ b/tracker/issueimport.py
@@ -0,0 +1,310 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Servlet to import a file of issues in JSON format.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import json
+import logging
+import time
+
+import ezt
+
+from features import filterrules_helpers
+from framework import framework_helpers
+from framework import jsonfeed
+from framework import permissions
+from framework import servlet
+from framework import urls
+from proto import tracker_pb2
+
+
+ParserState = collections.namedtuple(
+    'ParserState',
+    'user_id_dict, nonexist_emails, issue_list, comments_dict, starrers_dict, '
+    'relations_dict')
+
+
+class IssueImport(servlet.Servlet):
+  """IssueImport loads a file of issues in JSON format."""
+
+  _PAGE_TEMPLATE = 'tracker/issue-import-page.ezt'
+  _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
+
+  def AssertBasePermission(self, mr):
+    """Make sure that the logged in user has permission to view this page."""
+    super(IssueImport, self).AssertBasePermission(mr)
+    if not mr.auth.user_pb.is_site_admin:
+      raise permissions.PermissionException(
+          'Only site admins may import issues')
+
+  def GatherPageData(self, mr):
+    """Build up a dictionary of data values to use when rendering the page."""
+    return {
+        'issue_tab_mode': None,
+        'page_perms': self.MakePagePerms(mr, None, permissions.CREATE_ISSUE),
+        'import_errors': [],
+    }
+
+  def ProcessFormData(self, mr, post_data):
+    """Process the issue entry form.
+
+    Args:
+      mr: commonly used info parsed from the request.
+      post_data: The post_data dict for the current request.
+
+    Returns:
+      String URL to redirect the user to after processing.
+    """
+    import_errors = []
+    json_data = None
+
+    pre_check_only = 'pre_check_only' in post_data
+
+    uploaded_file = post_data.get('jsonfile')
+    if uploaded_file is None:
+      import_errors.append('No file uploaded')
+    else:
+      try:
+        json_str = uploaded_file.value
+        if json_str.startswith(jsonfeed.XSSI_PREFIX):
+          json_str = json_str[len(jsonfeed.XSSI_PREFIX):]
+        json_data = json.loads(json_str)
+      except ValueError:
+        import_errors.append('error parsing JSON in file')
+
+    if uploaded_file and not json_data:
+      import_errors.append('JSON file was empty')
+
+    # Note that the project must already exist in order to even reach
+    # this servlet because it is hosted in the context of a project.
+    if json_data and mr.project_name != json_data['metadata']['project']:
+      import_errors.append(
+        'Project name does not match. '
+        'Edit the file if you want to import into this project anyway.')
+
+    if import_errors:
+      return self.PleaseCorrect(mr, import_errors=import_errors)
+
+    event_log = []  # We accumulate a list of messages to display to the user.
+
+    try:
+      # First we parse the JSON into objects, but we don't have DB IDs yet.
+      state = self._ParseObjects(mr.cnxn, mr.project_id, json_data, event_log)
+      # If that worked, go ahead and start saving the data to the DB.
+      if not pre_check_only:
+        self._SaveObjects(mr.cnxn, mr.project_id, state, event_log)
+    except JSONImportError:
+      # just report it to the user by displaying event_log
+      event_log.append('Aborted import processing')
+
+    # This is a little bit of a hack because it always uses the form validation
+    # error message display logic to show the results of this import run,
+    # which may include errors or not.
+    return self.PleaseCorrect(mr, import_errors=event_log)
+
+  def _ParseObjects(self, cnxn, project_id, json_data, event_log):
+    """Examine JSON data and return a parser state for further processing."""
+    # Decide which users need to be created.
+    needed_emails = json_data['emails']
+    user_id_dict = self.services.user.LookupExistingUserIDs(cnxn, needed_emails)
+    nonexist_emails = [email for email in needed_emails
+                       if email not in user_id_dict]
+
+    event_log.append('Need to create %d users: %r' %
+                     (len(nonexist_emails), nonexist_emails))
+    user_id_dict.update({
+        email.lower(): framework_helpers.MurmurHash3_x86_32(email.lower())
+        for email in nonexist_emails})
+
+    num_comments = 0
+    num_stars = 0
+    issue_list = []
+    comments_dict = collections.defaultdict(list)
+    starrers_dict = collections.defaultdict(list)
+    relations_dict = collections.defaultdict(list)
+    for issue_json in json_data.get('issues', []):
+      issue, comment_list, starrer_list, relation_list = self._ParseIssue(
+          cnxn, project_id, user_id_dict, issue_json, event_log)
+      issue_list.append(issue)
+      comments_dict[issue.local_id] = comment_list
+      starrers_dict[issue.local_id] = starrer_list
+      relations_dict[issue.local_id] = relation_list
+      num_comments += len(comment_list)
+      num_stars += len(starrer_list)
+
+    event_log.append(
+      'Found info for %d issues: %r' %
+      (len(issue_list), sorted([issue.local_id for issue in issue_list])))
+
+    event_log.append(
+      'Found %d total comments for %d issues' %
+      (num_comments, len(comments_dict)))
+
+    event_log.append(
+      'Found %d total stars for %d issues' %
+      (num_stars, len(starrers_dict)))
+
+    event_log.append(
+      'Found %d total relationships.' %
+      sum((len(dsts) for dsts in relations_dict.values())))
+
+    event_log.append('Parsing phase finished OK')
+    return ParserState(
+      user_id_dict, nonexist_emails, issue_list,
+      comments_dict, starrers_dict, relations_dict)
+
+  def _ParseIssue(self, cnxn, project_id, user_id_dict, issue_json, event_log):
+    issue = tracker_pb2.Issue(
+      project_id=project_id,
+      local_id=issue_json['local_id'],
+      reporter_id=user_id_dict[issue_json['reporter']],
+      summary=issue_json['summary'],
+      opened_timestamp=issue_json['opened'],
+      modified_timestamp=issue_json['modified'],
+      cc_ids=[user_id_dict[cc_email]
+              for cc_email in issue_json.get('cc', [])
+              if cc_email in user_id_dict],
+      status=issue_json.get('status', ''),
+      labels=issue_json.get('labels', []),
+      field_values=[self._ParseFieldValue(cnxn, project_id, user_id_dict, field)
+                    for field in issue_json.get('fields', [])])
+    if issue_json.get('owner'):
+      issue.owner_id = user_id_dict[issue_json['owner']]
+    if issue_json.get('closed'):
+      issue.closed_timestamp = issue_json['closed']
+    comments = [self._ParseComment(
+                    project_id, user_id_dict, comment_json, event_log)
+                for comment_json in issue_json.get('comments', [])]
+
+    starrers = [user_id_dict[starrer] for starrer in issue_json['starrers']]
+
+    relations = []
+    relations.extend(
+        [(i, 'blockedon') for i in issue_json.get('blocked_on', [])])
+    relations.extend(
+        [(i, 'blocking') for i in issue_json.get('blocking', [])])
+    if 'merged_into' in issue_json:
+      relations.append((issue_json['merged_into'], 'mergedinto'))
+
+    return issue, comments, starrers, relations
+
+  def _ParseFieldValue(self, cnxn, project_id, user_id_dict, field_json):
+    field = tracker_pb2.FieldValue(
+        field_id=self.services.config.LookupFieldID(cnxn, project_id,
+                                                    field_json['field']))
+    if 'int_value' in field_json:
+      field.int_value = field_json['int_value']
+    if 'str_value' in field_json:
+      field.str_value = field_json['str_value']
+    if 'user_value' in field_json:
+      field.user_value = user_id_dict.get(field_json['user_value'])
+
+    return field
+
+  def _ParseComment(self, project_id, user_id_dict, comment_json, event_log):
+    comment = tracker_pb2.IssueComment(
+        # Note: issue_id is filled in after the issue is saved.
+        project_id=project_id,
+        timestamp=comment_json['timestamp'],
+        user_id=user_id_dict[comment_json['commenter']],
+        content=comment_json.get('content'))
+
+    for amendment in comment_json['amendments']:
+      comment.amendments.append(
+          self._ParseAmendment(amendment, user_id_dict, event_log))
+
+    for attachment in comment_json['attachments']:
+      comment.attachments.append(
+          self._ParseAttachment(attachment, event_log))
+
+    if comment_json['description_num']:
+      comment.is_description = True
+
+    return comment
+
+  def _ParseAmendment(self, amendment_json, user_id_dict, _event_log):
+    amendment = tracker_pb2.Amendment(
+        field=tracker_pb2.FieldID(amendment_json['field']))
+
+    if 'new_value' in amendment_json:
+      amendment.newvalue = amendment_json['new_value']
+    if 'custom_field_name' in amendment_json:
+      amendment.custom_field_name = amendment_json['custom_field_name']
+    if 'added_users' in amendment_json:
+      amendment.added_user_ids.extend(
+          [user_id_dict[email] for email in amendment_json['added_users']])
+    if 'removed_users' in amendment_json:
+      amendment.removed_user_ids.extend(
+          [user_id_dict[email] for email in amendment_json['removed_users']])
+
+    return amendment
+
+  def _ParseAttachment(self, attachment_json, _event_log):
+    attachment = tracker_pb2.Attachment(
+        filename=attachment_json['name'],
+        filesize=attachment_json['size'],
+        mimetype=attachment_json['mimetype'],
+        gcs_object_id=attachment_json['gcs_object_id']
+    )
+    return attachment
+
+  def _SaveObjects(self, cnxn, project_id, state, event_log):
+    """Examine JSON data and create users, issues, and comments."""
+
+    created_user_ids = self.services.user.LookupUserIDs(
+      cnxn, state.nonexist_emails, autocreate=True)
+    for created_email, created_id in created_user_ids.items():
+      if created_id != state.user_id_dict[created_email]:
+        event_log.append('Mismatched user_id for %r' % created_email)
+        raise JSONImportError()
+    event_log.append('Created %d users' % len(state.nonexist_emails))
+
+    total_comments = 0
+    total_stars = 0
+    config = self.services.config.GetProjectConfig(cnxn, project_id)
+    for issue in state.issue_list:
+      # TODO(jrobbins): renumber issues if there is a local_id conflict.
+      if issue.local_id not in state.starrers_dict:
+        # Issues with stars will have filter rules applied in SetStar().
+        filterrules_helpers.ApplyFilterRules(
+            cnxn, self.services, issue, config)
+      issue_id = self.services.issue.InsertIssue(cnxn, issue)
+      for comment in state.comments_dict[issue.local_id]:
+        total_comments += 1
+        comment.issue_id = issue_id
+        self.services.issue.InsertComment(cnxn, comment)
+      self.services.issue_star.SetStarsBatch(
+          cnxn, self.services, config, issue_id,
+          state.starrers_dict[issue.local_id], True)
+      total_stars += len(state.starrers_dict[issue.local_id])
+
+    event_log.append('Created %d issues' % len(state.issue_list))
+    event_log.append('Created %d comments for %d issues' % (
+        total_comments, len(state.comments_dict)))
+    event_log.append('Set %d stars on %d issues' % (
+        total_stars, len(state.starrers_dict)))
+
+    global_relations_dict = collections.defaultdict(list)
+    for issue, rels in state.relations_dict.items():
+      src_iid = self.services.issue.GetIssueByLocalID(
+          cnxn, project_id, issue).issue_id
+      dst_iids = [i.issue_id for i in self.services.issue.GetIssuesByLocalIDs(
+          cnxn, project_id, [rel[0] for rel in rels])]
+      kinds = [rel[1] for rel in rels]
+      global_relations_dict[src_iid] = list(zip(dst_iids, kinds))
+    self.services.issue.RelateIssues(cnxn, global_relations_dict)
+
+    self.services.issue.SetUsedLocalID(cnxn, project_id)
+    event_log.append('Finished import')
+
+
+class JSONImportError(Exception):
+  """Exception to raise if imported JSON is invalid."""
+  pass
