diff --git a/src/impl/diff.js b/src/impl/diff.js
index fc11678bc..7fe389b6e 100644
--- a/src/impl/diff.js
+++ b/src/impl/diff.js
@@ -22,23 +22,22 @@ function highOrderDiffs(cursor, later, units) {
   ];
 
   const results = {};
+  const earlier = cursor;
   let lowestOrder, highWater;
 
   for (const [unit, differ] of differs) {
     if (units.indexOf(unit) >= 0) {
       lowestOrder = unit;
 
-      let delta = differ(cursor, later);
-      highWater = cursor.plus({ [unit]: delta });
+      results[unit] = differ(cursor, later);
+      highWater = earlier.plus(results);
 
       if (highWater > later) {
-        cursor = cursor.plus({ [unit]: delta - 1 });
-        delta -= 1;
+        results[unit]--;
+        cursor = earlier.plus(results);
       } else {
         cursor = highWater;
       }
-
-      results[unit] = delta;
     }
   }
 
diff --git a/test/datetime/diff.test.js b/test/datetime/diff.test.js
index 3f0eeba28..d94725452 100644
--- a/test/datetime/diff.test.js
+++ b/test/datetime/diff.test.js
@@ -295,14 +295,24 @@ test("DateTime#diff results in a duration with the same locale", () => {
 
 // see https://github.com/moment/luxon/issues/487
 test("DateTime#diff results works when needing to backtrack months", () => {
-  const left = DateTime.fromJSDate(new Date(1554036127038));
-  const right = DateTime.fromJSDate(new Date(1554122527128));
+  const left = DateTime.fromJSDate(new Date(1554036127038)); // 2019-03-31T12:42:07.038Z
+  const right = DateTime.fromJSDate(new Date(1554122527128)); // 2019-04-01T12:42:07.128Z
 
   const diff = right.diff(left, ["months", "days", "hours"]);
   expect(diff.months).toBe(0);
   expect(diff.days).toBe(1);
 });
 
+// see https://github.com/moment/luxon/issues/1301
+test("DateTime#diff handles Feb-29 edge case logic for higher order units in a manner consistent with DateTime#plus", () => {
+  const left = DateTime.fromISO("2020-02-29");
+  const right = DateTime.fromISO("2021-04-01");
+
+  const diff = right.diff(left, ["years", "months", "days"]);
+  expect(diff.days).toBe(3);
+  expect(left.plus(diff).equals(right)).toBe(true);
+});
+
 //------
 // diffNow
 //-------