diff --git a/wa/workloads/gmail/__init__.py b/wa/workloads/gmail/__init__.py
index cdf7ae78..84b2f79b 100755
--- a/wa/workloads/gmail/__init__.py
+++ b/wa/workloads/gmail/__init__.py
@@ -36,6 +36,14 @@ class Gmail(ApkUiautoWorkload):
     6. Enter text in the Compose field
     7. Click the Send mail button
 
+    To run the workload in offline mode, a 'mailstore.tar' file is required. In order to
+    generate such a file, Gmail should first be operated from an Internet-connected environment.
+    After this, the relevant database files can be found in the
+    '/data/data/com.google.android.gm/databases' directory. These files can then be archived to
+    produce a tarball using a command such as ``tar -cvf mailstore.tar -C /path/to/databases .``.
+    The result should then be placed in the '~/.workload_automation/dependencies/gmail/' directory
+    on your local machine, creating this if it does not already exist.
+
     Known working APK version: 7.11.5.176133587
     '''
 
@@ -50,17 +58,36 @@ class Gmail(ApkUiautoWorkload):
                   An image to be copied onto the device that will be attached
                   to the email
                   '''),
+        Parameter('offline_mode', kind=bool, default=False, description='''
+                  If set to ``True``, the workload will execute in offline mode.
+                  This mode requires root and makes use of a tarball of email
+                  database files 'mailstore.tar' for the email account to be used.
+                  This file is extracted directly to the application's 'databases'
+                  directory at '/data/data/com.google.android.gm/databases'.
+                  '''),
     ]
 
-    # This workload relies on the internet so check that there is a working
-    # internet connection
-    requires_network = True
+    @property
+    def requires_network(self):
+        return not self.offline_mode
+
+    @property
+    def requires_rerun(self):
+        # In offline mode we need to restart the application after modifying its data directory
+        return self.offline_mode
 
     def __init__(self, target, **kwargs):
         super(Gmail, self).__init__(target, **kwargs)
         self.deployable_assets = [self.test_image]
+        if self.offline_mode:
+            self.deployable_assets.append('mailstore.tar')
         self.clean_assets = True
 
+    def initialize(self, context):
+        super(Gmail, self).initialize(context)
+        if self.offline_mode and not self.target.is_rooted:
+            raise WorkloadError('This workload requires root to set up Gmail for offline usage.')
+
     def init_resources(self, context):
         super(Gmail, self).init_resources(context)
         if self.target.get_sdk_version() >= 24 and 'com.google.android.apps.photos' not in self.target.list_packages():
@@ -70,6 +97,17 @@ class Gmail(ApkUiautoWorkload):
         work_dir = work_dir if work_dir[-1] != os.sep else work_dir[:-1]
         self.gui.uiauto_params['workdir_name'] = self.target.path.basename(work_dir)
         self.gui.uiauto_params['recipient'] = self.recipient
+        self.gui.uiauto_params['offline_mode'] = self.offline_mode
         # Only accept certain image formats
         if os.path.splitext(self.test_image.lower())[1] not in ['.jpg', '.jpeg', '.png']:
             raise ValidationError('{} must be a JPEG or PNG file'.format(self.test_image))
+
+    def setup_rerun(self):
+        super(Gmail, self).setup_rerun()
+        database_src = self.target.path.join(self.target.working_directory, 'mailstore.tar')
+        database_dst = self.target.path.join(self.target.package_data_directory, self.package, 'databases')
+        existing_mailstores = self.target.path.join(database_dst, 'mailstore.*')
+        owner = self.target.execute("{} stat -c '%u' {}".format(self.target.busybox, database_dst), as_root=True).strip()
+        self.target.execute('{} rm {}'.format(self.target.busybox, existing_mailstores), as_root=True)
+        self.target.execute('{} tar -xvf {} -C {}'.format(self.target.busybox, database_src, database_dst), as_root=True)
+        self.target.execute('{} chown -R {}:{} {}'.format(self.target.busybox, owner, owner, database_dst), as_root=True)
diff --git a/wa/workloads/gmail/com.arm.wa.uiauto.gmail.apk b/wa/workloads/gmail/com.arm.wa.uiauto.gmail.apk
index a32df324..60100c4e 100644
Binary files a/wa/workloads/gmail/com.arm.wa.uiauto.gmail.apk and b/wa/workloads/gmail/com.arm.wa.uiauto.gmail.apk differ
diff --git a/wa/workloads/gmail/uiauto/app/src/main/java/com/arm/wa/uiauto/gmail/UiAutomation.java b/wa/workloads/gmail/uiauto/app/src/main/java/com/arm/wa/uiauto/gmail/UiAutomation.java
index 257a5190..db60c503 100755
--- a/wa/workloads/gmail/uiauto/app/src/main/java/com/arm/wa/uiauto/gmail/UiAutomation.java
+++ b/wa/workloads/gmail/uiauto/app/src/main/java/com/arm/wa/uiauto/gmail/UiAutomation.java
@@ -39,6 +39,7 @@ public class UiAutomation extends BaseUiAutomation implements ApplaunchInterface
     protected String packageID;
     protected String recipient;
     protected String workdir_name;
+    protected boolean offlineMode;
 
     private int networkTimeoutSecs = 30;
     private long networkTimeout =  TimeUnit.SECONDS.toMillis(networkTimeoutSecs);
@@ -49,6 +50,7 @@ public class UiAutomation extends BaseUiAutomation implements ApplaunchInterface
         packageID = getPackageID(parameters);
         recipient = parameters.getString("recipient");
         workdir_name = parameters.getString("workdir_name");
+        offlineMode = parameters.getBoolean("offline_mode");
     }
 
     @Test
@@ -112,6 +114,11 @@ public class UiAutomation extends BaseUiAutomation implements ApplaunchInterface
             takeMeToBox.clickAndWaitForNewWindow(uiAutoTimeout);
         }
 
+        // If we're in offline mode we don't need to worry about syncing, so we're done
+        if (offlineMode) {
+            return;
+        }
+
         UiObject syncNowButton =
             mDevice.findObject(new UiSelector().textContains("Sync now")
                                          .className("android.widget.Button"));