diff --git a/patches/server/0925-Send-block-entities-after-destroy-prediction.patch b/patches/server/0925-Send-block-entities-after-destroy-prediction.patch
new file mode 100644
index 0000000000..c5f9f02261
--- /dev/null
+++ b/patches/server/0925-Send-block-entities-after-destroy-prediction.patch
@@ -0,0 +1,91 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
+Date: Sat, 25 Jun 2022 19:45:20 -0400
+Subject: [PATCH] Send block entities after destroy prediction
+
+Minecraft's prediction system does not handle block entities, so if we are manually sending block entities during
+block breaking we need to set it after the prediction is finished. This fixes block entities not showing when cancelling the BlockBreakEvent.
+
+diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+index 9378e83a67a70dbb1fb4f05b33f1e553d008e62b..5a60f5dc202c44b06ca34e9a19d45cb715f74fd3 100644
+--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
++++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+@@ -62,6 +62,8 @@ public class ServerPlayerGameMode {
+     private BlockPos delayedDestroyPos;
+     private int delayedTickStart;
+     private int lastSentState;
++    public boolean captureSentBlockEntities = false; // Paper
++    public boolean capturedBlockEntity = false; // Paper
+ 
+     public ServerPlayerGameMode(ServerPlayer player) {
+         this.gameModeForPlayer = GameType.DEFAULT_MODE;
+@@ -187,10 +189,7 @@ public class ServerPlayerGameMode {
+                     this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
+                     this.debugLogging(pos, false, sequence, "may not interact");
+                     // Update any tile entity data for this block
+-                    BlockEntity tileentity = this.level.getBlockEntity(pos);
+-                    if (tileentity != null) {
+-                        this.player.connection.send(tileentity.getUpdatePacket());
+-                    }
++                    capturedBlockEntity = true; // Paper - send block entity after predicting
+                     // CraftBukkit end
+                     return;
+                 }
+@@ -206,10 +205,7 @@ public class ServerPlayerGameMode {
+                     // Paper end
+                     this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
+                     // Update any tile entity data for this block
+-                    BlockEntity tileentity = this.level.getBlockEntity(pos);
+-                    if (tileentity != null) {
+-                        this.player.connection.send(tileentity.getUpdatePacket());
+-                    }
++                    capturedBlockEntity = true; // Paper - send block entity after predicting
+                     return;
+                 }
+                 // CraftBukkit end
+@@ -385,10 +381,12 @@ public class ServerPlayerGameMode {
+                 }
+ 
+                 // Update any tile entity data for this block
++                if (!captureSentBlockEntities) { // Paper - Toggle this location for capturing as this is used for api
+                 BlockEntity tileentity = this.level.getBlockEntity(pos);
+                 if (tileentity != null) {
+                     this.player.connection.send(tileentity.getUpdatePacket());
+                 }
++                } else {capturedBlockEntity = true;} // Paper end
+                 return false;
+             }
+         }
+diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+index adb9cde74295830e74241e522ae5766d436aadb1..ff7df8026f85b7ad51458a0b720a8baf71cd9bd1 100644
+--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+@@ -1873,8 +1873,28 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
+                     return;
+                 }
+                 // Paper end - Don't allow digging in unloaded chunks
++                // Paper start - send block entities after prediction
++                this.player.gameMode.capturedBlockEntity = false;
++                this.player.gameMode.captureSentBlockEntities = true;
++                // Paper end - send block entities after prediction
+                 this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight(), packet.getSequence());
+                 this.player.connection.ackBlockChangesUpTo(packet.getSequence());
++                // Paper start - send block entities after prediction
++                this.player.gameMode.captureSentBlockEntities = false;
++                // If a block entity was modified speedup the block change ack to avoid the block entity
++                // being overriden.
++                if (this.player.gameMode.capturedBlockEntity) {
++                    // manually tick
++                    this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo));
++                    this.player.connection.ackBlockChangesUpTo = -1;
++
++                    this.player.gameMode.capturedBlockEntity = false;
++                    BlockEntity tileentity = this.player.level.getBlockEntity(blockposition);
++                    if (tileentity != null) {
++                        this.player.connection.send(tileentity.getUpdatePacket());
++                    }
++                }
++                // Paper end - send block entities after prediction
+                 return;
+             default:
+                 throw new IllegalArgumentException("Invalid player action");