diff --git a/src/main/java/net/floodlightcontroller/core/IOFConnection.java b/src/main/java/net/floodlightcontroller/core/IOFConnection.java
index a14021fbd47b087495b57bdd3b1736966df0a798..21855fd33aeb96714451ae38d5dee1b88dc16383 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFConnection.java
@@ -1,11 +1,12 @@
 package net.floodlightcontroller.core;
 
 import java.net.SocketAddress;
-
 import java.util.Date;
+
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
+import org.projectfloodlight.openflow.types.U64;
 
 
 /** Contract for an openflow connection to a switch.
@@ -58,5 +59,9 @@ public interface IOFConnection extends IOFMessageWriter {
      */
     boolean isConnected();
 
-
+	/**
+	 * Get the one-way latency from the switch to the controller.
+	 * @return milliseconds
+	 */
+	public U64 getLatency();
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IOFConnectionBackend.java b/src/main/java/net/floodlightcontroller/core/IOFConnectionBackend.java
index 0ec7a9e1b2b081b34c813d5d9dd959028e1e49cc..aef346b86449910e59ddf0bd4938ba92cc34a8ea 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFConnectionBackend.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFConnectionBackend.java
@@ -1,5 +1,7 @@
 package net.floodlightcontroller.core;
 
+import org.projectfloodlight.openflow.types.U64;
+
 import net.floodlightcontroller.core.internal.IOFConnectionListener;
 
 public interface IOFConnectionBackend extends IOFConnection {
@@ -20,4 +22,21 @@ public interface IOFConnectionBackend extends IOFConnection {
 
     /** set the message/closing listener for this connection */
     void setListener(IOFConnectionListener listener);
+    
+    /**
+     * Update the present latency between the switch and
+     * the controller. The latency should be in milliseconds
+     * and should be one-way. The caller must convert all
+     * round-trip values to one-way prior to invoking this
+     * function.
+     * 
+     * The old link latency being updated will retain X%
+     * of the value, while the new link latency will attribute
+     * (100-X)%. This should allow new network configurations to
+     * quickly overtake old ones but will still allow
+     * outlier values to be absorbed.
+     * 
+     * @param latency
+     */
+    public void updateLatency(U64 latency);
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index df2c58a743918cc6c27aa89ec7e94dd064b65ed6..4cc47498d8534a5cce3f24e78243f4cac7313394 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -35,6 +35,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.U64;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -362,5 +363,10 @@ public interface IOFSwitch extends IOFMessageWriter {
      * @return
      */
 	short getNumTables();
-    
-}
+ 
+	/**
+	 * Get the one-way latency from the switch to the controller.
+	 * @return milliseconds
+	 */
+	public U64 getLatency();
+}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/NullConnection.java b/src/main/java/net/floodlightcontroller/core/NullConnection.java
index 41a5a1591bf631e2bd419b2ed996e1294dc3748a..34f225e1343a1f32953f786a61555cf053438f8d 100644
--- a/src/main/java/net/floodlightcontroller/core/NullConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/NullConnection.java
@@ -2,9 +2,10 @@ package net.floodlightcontroller.core;
 
 import java.net.SocketAddress;
 import java.util.List;
-
 import java.util.Date;
+
 import net.floodlightcontroller.core.internal.IOFConnectionListener;
+
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFMessage;
@@ -14,6 +15,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
+import org.projectfloodlight.openflow.types.U64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -111,4 +113,13 @@ public class NullConnection implements IOFConnectionBackend, IOFMessageWriter {
     public void setListener(IOFConnectionListener listener) {
     }
 
+	@Override
+	public U64 getLatency() {
+		return U64.ZERO;
+	}
+
+	@Override
+	public void updateLatency(U64 latency) {
+		// noop
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/OFConnection.java b/src/main/java/net/floodlightcontroller/core/OFConnection.java
index 36efb215975f38dbe22b41433485c0ba2a49d9b1..009b31bb9310b0d4110634fabbbf2b271b5b0b3c 100644
--- a/src/main/java/net/floodlightcontroller/core/OFConnection.java
+++ b/src/main/java/net/floodlightcontroller/core/OFConnection.java
@@ -51,6 +51,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.protocol.OFType;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
+import org.projectfloodlight.openflow.types.U64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -85,9 +86,10 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{
     private static final long DELIVERABLE_TIME_OUT = 60;
     private static final TimeUnit DELIVERABLE_TIME_OUT_UNIT = TimeUnit.SECONDS;
 
-
     private final OFConnectionCounters counters;
     private IOFConnectionListener listener;
+    
+    private volatile U64 latency;
 
     public OFConnection(@Nonnull DatapathId dpid,
                         @Nonnull OFFactory factory,
@@ -110,6 +112,7 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{
         this.xidDeliverableMap = new ConcurrentHashMap<>();
         this.counters = new OFConnectionCounters(debugCounters, dpid, this.auxId);
         this.timer = timer;
+        this.latency = U64.ZERO;
     }
 
     @Override
@@ -380,6 +383,27 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{
             listener.messageReceived(this, m);
         }
     }
+    
+    @Override
+    public U64 getLatency() {
+    	return this.latency;
+    }
+    
+    @Override
+    public void updateLatency(U64 latency) {
+    	if (latency == null) {
+			logger.error("Latency must be non-null. Ignoring null latency value.");
+			return;
+		} else if (this.latency.equals(U64.ZERO)) { 
+			logger.debug("Recording previously 0ms switch {} latency as {}ms", this.getDatapathId(), latency.getValue());
+			this.latency = latency;
+			return;
+		} else {
+			double oldWeight = 0.30;
+			this.latency = U64.of((long) (this.latency.getValue() * oldWeight + latency.getValue() * (1 - oldWeight)));
+			logger.debug("Switch {} latency updated to {}ms", this.getDatapathId(), this.latency.getValue());
+		}
+    }
 
     /** A dummy connection listener that just logs warn messages. Saves us a few null checks
      * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
@@ -409,6 +433,5 @@ public class OFConnection implements IOFConnection, IOFConnectionBackend{
 			// TODO Auto-generated method stub
 			
 		}
-
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitch.java b/src/main/java/net/floodlightcontroller/core/OFSwitch.java
index 146bfe19179531501d1f36c66a0404575f70c7ce..16684795ec488d7b0cdc71ba32218d462a8f1ad3 100644
--- a/src/main/java/net/floodlightcontroller/core/OFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/OFSwitch.java
@@ -69,6 +69,7 @@ import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.U64;
 
 import net.floodlightcontroller.util.LinkedHashSetWrapper;
 import net.floodlightcontroller.util.OrderedCollection;
@@ -124,7 +125,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	private SwitchStatus status;
 
 	public static final int OFSWITCH_APP_ID = ident(5);
-	
+
 	private TableId maxTableToGetTableMissFlow = TableId.of(4); /* this should cover most HW switches that have a couple SW flow tables */
 
 	static {
@@ -759,7 +760,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	public void write(Iterable<OFMessage> msglist, LogicalOFMessageCategory category) {
 		if (isActive()) {
 			this.getConnection(category).write(msglist);
-			
+
 			for(OFMessage m : msglist) {
 				switchManager.handleOutgoingMessage(this, m);				
 			}
@@ -793,7 +794,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	public void write(Iterable<OFMessage> msglist) {
 		if (isActive()) {
 			connections.get(OFAuxId.MAIN).write(msglist);
-						
+
 			for(OFMessage m : msglist) {
 				switchManager.handleOutgoingMessage(this, m);
 			}
@@ -831,7 +832,7 @@ public class OFSwitch implements IOFSwitchBackend {
 			/* OF1.3+ Per-table actions are set later in the OFTableFeaturesRequest/Reply */
 			this.actions = featuresReply.getActions();
 		}
-		
+
 		this.nTables = featuresReply.getNTables();
 	}
 
@@ -986,7 +987,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	private <REPLY extends OFStatsReply> ListenableFuture<List<REPLY>> addInternalStatsReplyListener(final ListenableFuture<List<REPLY>> future, OFStatsRequest<REPLY> request) {
 		switch (request.getStatsType()) {
 		case TABLE_FEATURES:
-		/* case YOUR_CASE_HERE */
+			/* case YOUR_CASE_HERE */
 			future.addListener(new Runnable() {
 				/*
 				 * We know the reply will be a list of OFStatsReply.
@@ -1009,7 +1010,7 @@ public class OFSwitch implements IOFSwitchBackend {
 							case TABLE_FEATURES:
 								processOFTableFeatures((List<OFTableFeaturesStatsReply>) future.get());
 								break;
-							/* case YOUR_CASE_HERE */
+								/* case YOUR_CASE_HERE */
 							default:
 								throw new Exception("Received an invalid OFStatsReply of " 
 										+ replies.get(0).getStatsType().toString() + ". Expected TABLE_FEATURES.");
@@ -1097,7 +1098,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	public Collection<TableId> getTables() {
 		return new ArrayList<TableId>(tables);
 	}
-	
+
 	@Override
 	public short getNumTables() {
 		return this.nTables;
@@ -1236,7 +1237,7 @@ public class OFSwitch implements IOFSwitchBackend {
 	public TableId getMaxTableForTableMissFlow() {
 		return maxTableToGetTableMissFlow;
 	}
-	
+
 	@Override
 	public TableId setMaxTableForTableMissFlow(TableId max) {
 		if (max.getValue() >= nTables) {
@@ -1246,4 +1247,9 @@ public class OFSwitch implements IOFSwitchBackend {
 		}
 		return maxTableToGetTableMissFlow;
 	}
-}
+
+	@Override
+	public U64 getLatency() {
+		return this.connections.get(OFAuxId.MAIN).getLatency();
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
index a6702b74f6b014a498c41c0f9263e5cba8742eaa..8f3cbedb6d168729a0582c41e0630d95fb4c599b 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
@@ -53,6 +53,7 @@ import org.projectfloodlight.openflow.protocol.ver13.OFHelloElemTypeSerializerVe
 import org.projectfloodlight.openflow.protocol.ver14.OFHelloElemTypeSerializerVer14;
 import org.projectfloodlight.openflow.types.OFAuxId;
 import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -84,6 +85,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
 	 * We will count down
 	 */
 	private long handshakeTransactionIds = 0x00FFFFFFFFL;
+	
+    private volatile long echoSendTime;
 
 
 	/**
@@ -107,11 +110,12 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
 
 		void processOFEchoReply(OFEchoReply m)
 				throws IOException {
-			// do nothing
+			/* Update the latency -- halve it for one-way time */
+			updateLatency(U64.of( (System.currentTimeMillis() - echoSendTime) / 2) );
 		}
 
 		void processOFError(OFErrorMsg m) {
-			logErrorDisconnect(m);
+			logErrorDisconnect(m); 
 		}
 
 		void processOFExperimenter(OFExperimenter m) {
@@ -880,13 +884,15 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
 				.build();
 		
 		channel.write(Collections.singletonList(m));
-		log.debug("Send hello: {}", m);
+		log.debug("Send hello: {}", m); 
 	}
 
 	private void sendEchoRequest() {
 		OFEchoRequest request = factory.buildEchoRequest()
 				.setXid(handshakeTransactionIds--)
 				.build();
+		/* Record for latency calculation */
+		echoSendTime = System.currentTimeMillis();
 		channel.write(Collections.singletonList(request));
 	}
 
@@ -910,4 +916,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
 		return this.pipeline;
 	}
 
+	private void updateLatency(U64 latency) {
+		if (connection != null) {
+			connection.updateLatency(latency);
+		}
+	}
 }
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index e8f073aa33118a3f71e347e4669f66878c5a9083..26dd12e59f4bbe46364e9e669d0fb941d86a9656 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -378,7 +378,7 @@ IFloodlightModule, IInfoProvider {
 				.put((byte) 0x26)
 				.put((byte) 0xe1)
 				.put((byte) 0x01) /* 0x01 is what we'll use to differentiate DPID (0x00) from time (0x01) */
-				.putLong(System.currentTimeMillis())
+				.putLong(System.currentTimeMillis() + iofSwitch.getLatency().getValue() /* account for our switch's one-way latency */)
 				.array();
 
 		LLDPTLV timestampTLV = new LLDPTLV()
@@ -691,8 +691,8 @@ IFloodlightModule, IInfoProvider {
 					&& lldptlv.getValue()[1] == 0x26
 					&& lldptlv.getValue()[2] == (byte) 0xe1
 					&& lldptlv.getValue()[3] == 0x01) { /* 0x01 for timestamp */
-				ByteBuffer tsBB = ByteBuffer.wrap(lldptlv.getValue());
-				timestamp = tsBB.getLong(4); /* skip OpenFlow OUI (4 bytes above) */
+				ByteBuffer tsBB = ByteBuffer.wrap(lldptlv.getValue()); /* skip OpenFlow OUI (4 bytes above) */
+				timestamp = tsBB.getLong(4) + iofSwitch.getLatency().getValue(); /* include the RX switch latency to "subtract" it */
 			} else if (lldptlv.getType() == 12 && lldptlv.getLength() == 8) {
 				otherId = ByteBuffer.wrap(lldptlv.getValue()).getLong();
 				if (myId == otherId) myLLDP = true;
diff --git a/src/main/resources/logback-test.xml b/src/main/resources/logback-test.xml
index 487bbc58a2303978334014d2b55dabd86d83ac52..b5e3bfd8093df991c049e5f86e873a9834d12747 100644
--- a/src/main/resources/logback-test.xml
+++ b/src/main/resources/logback-test.xml
@@ -17,7 +17,7 @@
   <logger name="net.floodlightcontroller.devicemanager" level="INFO"></logger>
   <logger name="net.floodlightcontroller.linkdiscovery" level="INFO"></logger>
   <logger name="net.floodlightcontroller.forwarding" level="INFO"></logger>
-  <logger name="net.floodlightcontroller.core.internal" level="INFO"></logger>
+  <logger name="net.floodlightcontroller.core" level="INFO"></logger>
   <logger name="net.floodlightcontroller.topology" level="INFO" ></logger>
   <logger name="org.projectfloodlight.openflow" level="INFO" ></logger>
 </configuration>
diff --git a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
index 64631b78afd5cfe93e065ddac678717aec507579..c1eab8ba8baedd748aaddeb089504befb4cad6a0 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/MockOFConnection.java
@@ -7,9 +7,10 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import java.util.Date;
+
 import net.floodlightcontroller.core.IOFConnectionBackend;
+
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFRequest;
@@ -17,6 +18,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsReply;
 import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFAuxId;
+import org.projectfloodlight.openflow.types.U64;
 
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -214,4 +216,16 @@ public class MockOFConnection implements IOFConnectionBackend {
     public OFMessage retrieveMessage() {
         return this.messages.remove(0);
     }
+
+	@Override
+	public U64 getLatency() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void updateLatency(U64 latency) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index 845f8bec08124cdce5aaaf6bf2e3eff93121744d..cd7fe7ae38caec6fa499d4fcec08155cf2631ce3 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -468,6 +468,7 @@ public class LinkDiscoveryManagerTest extends FloodlightTestCase {
         expect(sw1.getEnabledPortNumbers()).andReturn(ports).anyTimes();
         expect(sw1.getPort(OFPort.of(EasyMock.anyInt()))).andReturn(ofpp).anyTimes();
         expect(sw1.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes();
+        expect(sw1.getLatency()).andReturn(U64.ZERO).anyTimes();
         sw1.write(capture(wc));
         expectLastCall().anyTimes();
         replay(sw1);
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 1416e8353b59fb7b82bf42a5ad95a8d37c2eb10e..c4005b32aaec719cfd0f4f43732bacc941f75bb3 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -44,6 +44,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsRequest;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.U64;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -348,4 +349,10 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
 		// TODO Auto-generated method stub
 		return null;
 	}
+
+	@Override
+	public U64 getLatency() {
+		// TODO Auto-generated method stub
+		return null;
+	}
 }