diff --git a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
index 3d0886cfc..cdf7fcfc1 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -24,6 +24,8 @@
 import com.wireguard.util.NonNullForAll;
 
 import java.net.InetAddress;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
@@ -125,12 +127,16 @@ public Statistics getStatistics(final Tunnel tunnel) {
         Key key = null;
         long rx = 0;
         long tx = 0;
+        long lastHandshakeTimeSec = 0;
+        int lastHandshakeTimeNSec = 0;
         for (final String line : config.split("\\n")) {
             if (line.startsWith("public_key=")) {
                 if (key != null)
-                    stats.add(key, rx, tx);
+                    stats.add(key, rx, tx, LocalDateTime.ofEpochSecond(lastHandshakeTimeSec, lastHandshakeTimeNSec, ZoneOffset.UTC));
                 rx = 0;
                 tx = 0;
+                lastHandshakeTimeSec = 0;
+                lastHandshakeTimeNSec = 0;
                 try {
                     key = Key.fromHex(line.substring(11));
                 } catch (final KeyFormatException ignored) {
@@ -152,10 +158,26 @@ public Statistics getStatistics(final Tunnel tunnel) {
                 } catch (final NumberFormatException ignored) {
                     tx = 0;
                 }
+            } else if (line.startsWith("last_handshake_time_sec=")) {
+                if (key == null)
+                    continue;
+                try {
+                    lastHandshakeTimeSec = Long.parseLong(line.substring(24));
+                } catch (final NumberFormatException ignored) {
+                    lastHandshakeTimeSec = 0;
+                }
+            } else if (line.startsWith("last_handshake_time_nsec=")) {
+                if (key == null)
+                    continue;
+                try {
+                    lastHandshakeTimeNSec = Integer.parseInt(line.substring(25));
+                } catch (final NumberFormatException ignored) {
+                    lastHandshakeTimeNSec = 0;
+                }
             }
         }
         if (key != null)
-            stats.add(key, rx, tx);
+            stats.add(key, rx, tx, LocalDateTime.ofEpochSecond(lastHandshakeTimeSec, lastHandshakeTimeNSec, ZoneOffset.UTC));
         return stats;
     }
 
@@ -237,7 +259,8 @@ private void setStateInternal(final Tunnel tunnel, @Nullable final Config config
             }
 
 
-            dnsRetry: for (int i = 0; i < DNS_RESOLUTION_RETRIES; ++i) {
+            dnsRetry:
+            for (int i = 0; i < DNS_RESOLUTION_RETRIES; ++i) {
                 // Pre-resolve IPs so they're cached when building the userspace string
                 for (final Peer peer : config.getPeers()) {
                     final InetEndpoint ep = peer.getEndpoint().orElse(null);
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/PeerStatistics.java b/tunnel/src/main/java/com/wireguard/android/backend/PeerStatistics.java
new file mode 100644
index 000000000..4f95c4271
--- /dev/null
+++ b/tunnel/src/main/java/com/wireguard/android/backend/PeerStatistics.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2017-2021 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend;
+
+import com.wireguard.util.NonNullForAll;
+
+import java.time.LocalDateTime;
+
+/**
+ * Class representing transfer statistics and last handshake time for a
+ * {@link com.wireguard.config.Peer} instance.
+ */
+@NonNullForAll
+public class PeerStatistics {
+    private final long rx;
+    private final long tx;
+    private final LocalDateTime lastHandshakeTime;
+
+    /**
+     * Create a peer statistics data object.
+     *
+     * @param rx                The received traffic for the {@link com.wireguard.config.Peer}.
+     *                          This value is in bytes
+     * @param tx                The transmitted traffic for the {@link com.wireguard.config.Peer}.
+     *                          This value is in bytes.
+     * @param lastHandshakeTime The last handshake time for the {@link com.wireguard.config.Peer}.
+     *                          This value is in LocalDateTime.
+     */
+    PeerStatistics(long rx, long tx, LocalDateTime lastHandshakeTime) {
+        this.rx = rx;
+        this.tx = tx;
+        this.lastHandshakeTime = lastHandshakeTime;
+    }
+
+    /**
+     * Get the received traffic (in bytes) for the {@link com.wireguard.config.Peer}
+     *
+     * @return a long representing the number of bytes received by this peer.
+     */
+    public long getRx() {
+        return rx;
+    }
+
+    /**
+     * Get the transmitted traffic (in bytes) for the {@link com.wireguard.config.Peer}
+     *
+     * @return a long representing the number of bytes transmitted by this peer.
+     */
+    public long getTx() {
+        return tx;
+    }
+
+    /**
+     * Get last handshake time for the {@link com.wireguard.config.Peer}
+     *
+     * @return a LocalDateTime.
+     */
+    public LocalDateTime getLastHandshakeTime() {
+        return lastHandshakeTime;
+    }
+}
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/Statistics.java b/tunnel/src/main/java/com/wireguard/android/backend/Statistics.java
index 5d658019c..d0cb3745c 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/Statistics.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/Statistics.java
@@ -6,21 +6,24 @@
 package com.wireguard.android.backend;
 
 import android.os.SystemClock;
-import android.util.Pair;
 
 import com.wireguard.crypto.Key;
 import com.wireguard.util.NonNullForAll;
 
+import java.time.ZoneOffset;
 import java.util.HashMap;
 import java.util.Map;
+import java.time.LocalDateTime;
 
 /**
  * Class representing transfer statistics for a {@link Tunnel} instance.
  */
 @NonNullForAll
 public class Statistics {
-    private final Map<Key, Pair<Long, Long>> peerBytes = new HashMap<>();
+    private final Map<Key, PeerStatistics> peerStats = new HashMap<>();
     private long lastTouched = SystemClock.elapsedRealtime();
+    private LocalDateTime defaultLastHandshakeTime = LocalDateTime.ofEpochSecond(
+            0, 0, ZoneOffset.UTC);
 
     Statistics() {
     }
@@ -28,14 +31,16 @@ public class Statistics {
     /**
      * Add a peer and its current data usage to the internal map.
      *
-     * @param key A WireGuard public key bound to a particular peer
-     * @param rx  The received traffic for the {@link com.wireguard.config.Peer} referenced by
-     *            the provided {@link Key}. This value is in bytes
-     * @param tx  The transmitted traffic for the {@link com.wireguard.config.Peer} referenced by
-     *            the provided {@link Key}. This value is in bytes.
+     * @param key               A WireGuard public key bound to a particular peer
+     * @param rx                The received traffic for the {@link com.wireguard.config.Peer} referenced by
+     *                          the provided {@link Key}. This value is in bytes
+     * @param tx                The transmitted traffic for the {@link com.wireguard.config.Peer} referenced by
+     *                          the provided {@link Key}. This value is in bytes.
+     * @param lastHandshakeTime The last handshake time for the {@link com.wireguard.config.Peer} referenced by
+     *                          the provided {@link Key}. This value is in LocalDateTime.
      */
-    void add(final Key key, final long rx, final long tx) {
-        peerBytes.put(key, Pair.create(rx, tx));
+    void add(final Key key, final long rx, final long tx, final LocalDateTime lastHandshakeTime) {
+        peerStats.put(key, new PeerStatistics(rx, tx, lastHandshakeTime));
         lastTouched = SystemClock.elapsedRealtime();
     }
 
@@ -56,10 +61,10 @@ public boolean isStale() {
      * @return a long representing the number of bytes received by this peer.
      */
     public long peerRx(final Key peer) {
-        final Pair<Long, Long> rxTx = peerBytes.get(peer);
-        if (rxTx == null)
+        final PeerStatistics stats = peerStats.get(peer);
+        if (stats == null)
             return 0;
-        return rxTx.first;
+        return stats.getRx();
     }
 
     /**
@@ -70,10 +75,24 @@ public long peerRx(final Key peer) {
      * @return a long representing the number of bytes transmitted by this peer.
      */
     public long peerTx(final Key peer) {
-        final Pair<Long, Long> rxTx = peerBytes.get(peer);
-        if (rxTx == null)
+        final PeerStatistics stats = peerStats.get(peer);
+        if (stats == null)
             return 0;
-        return rxTx.second;
+        return stats.getTx();
+    }
+
+    /**
+     * Get the last handshake time for the {@link com.wireguard.config.Peer} referenced by
+     * the provided {@link Key}
+     *
+     * @param peer A {@link Key} representing a {@link com.wireguard.config.Peer}.
+     * @return a LocalDateTime representing the last handshake time by this peer.
+     */
+    public LocalDateTime peerLastHandshakeTime(final Key peer) {
+        final PeerStatistics info = peerStats.get(peer);
+        if (info == null)
+            return defaultLastHandshakeTime;
+        return info.getLastHandshakeTime();
     }
 
     /**
@@ -83,7 +102,7 @@ public long peerTx(final Key peer) {
      * {@link com.wireguard.config.Peer}s
      */
     public Key[] peers() {
-        return peerBytes.keySet().toArray(new Key[0]);
+        return peerStats.keySet().toArray(new Key[0]);
     }
 
     /**
@@ -93,8 +112,8 @@ public Key[] peers() {
      */
     public long totalRx() {
         long rx = 0;
-        for (final Pair<Long, Long> val : peerBytes.values()) {
-            rx += val.first;
+        for (final PeerStatistics val : peerStats.values()) {
+            rx += val.getRx();
         }
         return rx;
     }
@@ -106,8 +125,8 @@ public long totalRx() {
      */
     public long totalTx() {
         long tx = 0;
-        for (final Pair<Long, Long> val : peerBytes.values()) {
-            tx += val.second;
+        for (final PeerStatistics val : peerStats.values()) {
+            tx += val.getTx();
         }
         return tx;
     }