diff --git a/internal/api/block_documents.go b/internal/api/block_documents.go
index f792b13d..526badac 100644
--- a/internal/api/block_documents.go
+++ b/internal/api/block_documents.go
@@ -37,7 +37,7 @@ type BlockDocumentCreate struct {
 }
 
 type BlockDocumentUpdate struct {
-	BlockSchemaID     *uuid.UUID             `json:"block_schema_id"`
+	BlockSchemaID     uuid.UUID              `json:"block_schema_id"`
 	Data              map[string]interface{} `json:"data"`
 	MergeExistingData bool                   `json:"merge_existing_data"`
 }
diff --git a/internal/provider/resources/block.go b/internal/provider/resources/block.go
index fd5b8f15..9a6d7146 100644
--- a/internal/provider/resources/block.go
+++ b/internal/provider/resources/block.go
@@ -106,6 +106,9 @@ func (r *BlockResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
 			"type_slug": schema.StringAttribute{
 				Required:    true,
 				Description: "Block Type slug, which determines the schema of the `data` JSON attribute. Use `prefect block types ls` to view all available Block type slugs.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
 			},
 			"data": schema.StringAttribute{
 				Required:    true,
@@ -256,6 +259,8 @@ func (r *BlockResource) Read(ctx context.Context, req resource.ReadRequest, resp
 			"Error creating block client",
 			fmt.Sprintf("Could not create block client, unexpected error: %s. This is a bug in the provider, please report this to the maintainers.", err.Error()),
 		)
+
+		return
 	}
 
 	var blockID uuid.UUID
@@ -306,9 +311,121 @@ func (r *BlockResource) Read(ctx context.Context, req resource.ReadRequest, resp
 }
 
 // Update updates the resource and sets the updated Terraform state on success.
-//
-//nolint:revive // TODO: remove this comment when method is implemented
 func (r *BlockResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+	var plan BlockResourceModel
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	blockTypeClient, err := r.client.BlockTypes(plan.AccountID.ValueUUID(), plan.WorkspaceID.ValueUUID())
+	if err != nil {
+		resp.Diagnostics.Append(helpers.CreateClientErrorDiagnostic("Block Types", err))
+
+		return
+	}
+
+	blockSchemaClient, err := r.client.BlockSchemas(plan.AccountID.ValueUUID(), plan.WorkspaceID.ValueUUID())
+	if err != nil {
+		resp.Diagnostics.Append(helpers.CreateClientErrorDiagnostic("Block Schema", err))
+
+		return
+	}
+
+	blockDocumentClient, err := r.client.BlockDocuments(plan.AccountID.ValueUUID(), plan.WorkspaceID.ValueUUID())
+	if err != nil {
+		resp.Diagnostics.Append(helpers.CreateClientErrorDiagnostic("Block Document", err))
+
+		return
+	}
+
+	blockType, err := blockTypeClient.GetBySlug(ctx, plan.TypeSlug.ValueString())
+	if err != nil {
+		resp.Diagnostics.Append(helpers.ResourceClientErrorDiagnostic("Block Type", "get_by_slug", err))
+
+		return
+	}
+
+	blockSchemas, err := blockSchemaClient.List(ctx, []uuid.UUID{blockType.ID})
+	if err != nil {
+		resp.Diagnostics.Append(helpers.ResourceClientErrorDiagnostic("Block Schema", "list", err))
+
+		return
+	}
+
+	if len(blockSchemas) == 0 {
+		resp.Diagnostics.AddError(
+			"No block schemas found",
+			fmt.Sprintf("No block schemas found for %s block type slug", plan.TypeSlug.ValueString()),
+		)
+
+		return
+	}
+
+	latestBlockSchema := blockSchemas[0]
+
+	blockID, err := uuid.Parse(plan.ID.ValueString())
+	if err != nil {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("id"),
+			"Error parsing block ID",
+			fmt.Sprintf("Could not parse block ID to UUID, unexpected error: %s", err.Error()),
+		)
+
+		return
+	}
+
+	var data map[string]interface{}
+	resp.Diagnostics.Append(plan.Data.Unmarshal(&data)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	err = blockDocumentClient.Update(ctx, blockID, api.BlockDocumentUpdate{
+		BlockSchemaID:     latestBlockSchema.ID,
+		Data:              data,
+		MergeExistingData: true,
+	})
+
+	if err != nil {
+		resp.Diagnostics.Append(helpers.ResourceClientErrorDiagnostic("Block Document", "update", err))
+
+		return
+	}
+
+	block, err := blockDocumentClient.Get(ctx, blockID)
+	if err != nil {
+		resp.Diagnostics.AddError(
+			"Error refreshing block state",
+			fmt.Sprintf("Could not read block, unexpected error: %s", err.Error()),
+		)
+
+		return
+	}
+
+	diags := copyBlockToModel(block, &plan)
+	resp.Diagnostics.Append(diags...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	byteSlice, err := json.Marshal(block.Data)
+	if err != nil {
+		diags.AddAttributeError(
+			path.Root("data"),
+			"Failed to serialize Block Data",
+			fmt.Sprintf("Could not serialize Block Data as JSON string: %s", err.Error()),
+		)
+
+		return
+	}
+	plan.Data = jsontypes.NewNormalizedValue(string(byteSlice))
+
+	diags = resp.State.Set(ctx, &plan)
+	resp.Diagnostics.Append(diags...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
 }
 
 // Delete deletes the resource and removes the Terraform state on success.