You want media_handle_sideload()
Handles a side-loaded file in the same way as an uploaded file is handled by media_handle_upload().
// Array similar to a $_FILES upload array.
$file_array = array(
'name' => 'filename.jpg',
'tmp_name' => 'path/to/filename.jpg',
);
// Post ID to attach upload to, 0 for none.
$post_id = 0;
$attachment_id = media_handle_sideload( $file_array, $post_id );