--- a/net/minecraft/resources/RegistryDataLoader.java
+++ b/net/minecraft/resources/RegistryDataLoader.java
@@ -247,13 +_,14 @@
         RegistryOps<JsonElement> ops,
         ResourceKey<E> resourceKey,
         Resource resource,
-        RegistrationInfo registrationInfo
+        RegistrationInfo registrationInfo,
+        io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions
     ) throws IOException {
         try (Reader reader = resource.openAsReader()) {
             JsonElement jsonElement = JsonParser.parseReader(reader);
             DataResult<E> dataResult = codec.parse(ops, jsonElement);
             E orThrow = dataResult.getOrThrow();
-            registry.register(resourceKey, orThrow, registrationInfo);
+            io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(registry, resourceKey, orThrow, registrationInfo, conversions); // Paper - register with listeners
         }
     }
 
@@ -267,6 +_,7 @@
         FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
         RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
 
+        final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryInfoLookup); // Paper - create conversions
         for (Entry<ResourceLocation, Resource> entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) {
             ResourceLocation resourceLocation = entry.getKey();
             ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation));
@@ -274,7 +_,7 @@
             RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo());
 
             try {
-                loadElementFromResource(registry, codec, registryOps, resourceKey, resource, registrationInfo);
+                loadElementFromResource(registry, codec, registryOps, resourceKey, resource, registrationInfo, conversions); // Paper - pass conversions
             } catch (Exception var14) {
                 loadingErrors.put(
                     resourceKey,
@@ -283,7 +_,9 @@
             }
         }
 
-        TagLoader.loadTagsForRegistry(resourceManager, registry);
+        io.papermc.paper.registry.PaperRegistryAccess.instance().lockReferenceHolders(registry.key()); // Paper - lock reference holders
+        io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners
+        TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause
     }
 
     static <E> void loadContentsFromNetwork(
@@ -300,6 +_,7 @@
             RegistryOps<JsonElement> registryOps1 = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup);
             FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
 
+            final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryInfoLookup); // Paper - create conversions
             for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) {
                 ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id());
                 Optional<Tag> optional = packedRegistryEntry.data();
@@ -318,7 +_,7 @@
 
                     try {
                         Resource resourceOrThrow = resourceProvider.getResourceOrThrow(resourceLocation);
-                        loadElementFromResource(registry, codec, registryOps1, resourceKey, resourceOrThrow, NETWORK_REGISTRATION_INFO);
+                        loadElementFromResource(registry, codec, registryOps1, resourceKey, resourceOrThrow, NETWORK_REGISTRATION_INFO, conversions); // Paper - pass conversions
                     } catch (Exception var17) {
                         loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17));
                     }
@@ -360,6 +_,7 @@
 
         RegistryDataLoader.Loader<T> create(Lifecycle registryLifecycle, Map<ResourceKey<?>, Exception> loadingErrors) {
             WritableRegistry<T> writableRegistry = new MappedRegistry<>(this.key, registryLifecycle);
+            io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(this.key, writableRegistry); // Paper - initialize API registry
             return new RegistryDataLoader.Loader<>(this, writableRegistry, loadingErrors);
         }
 
