This expression breaks the boundary of the parcel polygons into line segments, then finds the segment whose centroid is closest to the corresponding street in the address of the point. The centroid of that segment is then returned as the location to place the label.
The expression to apply on the point layer:
QGIS >=3.28
with_variable('street',
get_feature('streets', 'name', "street"), -- where 'streets' is the name of the streets layer and 'name' is the attribute field containing the name/code of the street
with_variable('bnd',
boundary( -- get the boundary of the parcel as a line
geometry(
get_feature('parcels', 'parcel', "parcel") -- where 'parcels' is the name of the parcel layer and 'parcel' is the attiribute field containing the name/code of the parcel
)
),
with_variable('segments', geometries_to_array(segments_to_lines(@bnd)), -- break boundary into segments and convert multiline to an array of individual geometries
with_variable('dists',
array_foreach( -- loop over the array of geometries and get the distance from the centroid to the corresponding street
@segments,
distance(geometry(@street), centroid(@element))
),
-- get the position in the array of the shortest distance and then use that position to find the geometry in the @segments array
centroid( array_get(@segments, array_find(@dists, array_min(@dists))) )
)
)
)
)
In the image, the blue points are the originals, and the red points signify the location of the label. I used points to make things clearer visually, but the same expression can be used in the Geometry Generator of the label placement options.

An adaptation to the expression to move the point a set distance inside the parcel:
with_variable('street',
get_feature('streets', 'name', "street"),
with_variable('bnd',
boundary(
geometry(
get_feature('parcels', 'parcel', "parcel")
)
),
with_variable('segments', geometries_to_array(segments_to_lines(@bnd)),
with_variable('dists',
array_foreach(
@segments,
distance(geometry(@street), centroid(@element))
),
-- make a line between the parcel centroid and the centroid of the segment
with_variable('line',
make_line(centroid(@bnd), centroid( array_get(@segments, array_find(@dists, array_min(@dists))) )),
-- cut this line short by a specified distance (5m) and get its endpoint (the new label position)
end_point(line_substring(@line, 0, length(@line) - 5))
)
)
)
)
)

Without the use of geometries_to_array
function (QGIS <3.28)
The second expression rewritten for versions of QGIS prior to the geometries_to_array
function being added:
with_variable('street',
get_feature('streets', 'name', "street"),
with_variable('bnd',
boundary(
geometry(
get_feature('parcels', 'parcel', "parcel")
)
),
with_variable('segments',
array_foreach(
generate_series(1, num_geometries(segments_to_lines(@bnd))),
geometry_n(segments_to_lines(@bnd), @element)
),
with_variable('dists',
array_foreach( -- loop over the array of geometries and get the distance from the centroid to the corresponding street
@segments,
distance(geometry(@street), centroid(@element))
),
-- make a line between the parcel centroid and the centroid of the segment
with_variable('line',
make_line(centroid(@bnd), centroid( array_get(@segments, array_find(@dists, array_min(@dists))) )),
-- cut this line short by a specified distance (5m) and get its endpoint (the new label position)
end_point(line_substring(@line, 0, length(@line) - 5))
)
)
)
)
)